Break values in one column into multiple rows - sql

I am trying to explode values belonging to one id into multiple rows.
category_id subcategory_ids
123 111
123
333
465 444
555
The result I am trying to achieve should look like below-
category_id subcategory_ids
123 111
123 123
123 333
465 444
465 555

Below is for BigQuery Standard SQL
#standardSQL
SELECT category_id, subcategory_ids
FROM `project.dataset.table`,
UNNEST(subcategory_ids) subcategory_ids

Related

Postgres SQL to extract rows based on sequence number

I have data in Telephone table, something as below:
ID
area
exch
line
ext
tel_type_cde
tel_seq_num
modified_dttm
1234
482
876
789
1234
0
0
01-01-2023
1234
483
877
123
0
1
01-02-2023
1234
123
234
456
1234
1
0
01-01-2023
1235
483
877
456
0
1
01-01-2023
1236
483
877
123
0
0
01-02-2023
1236
123
234
456
1234
0
1
01-02-2023
1236
483
877
458
0
2
01-03-2023
For an ID/tel_type_cde combination there might be multiple rows and telephone sequence number is used to derive from latest number which needs to considered further
Expected output
ID
area
exch
line
ext
tel_type_cde
1234
483
877
123
0
1234
123
234
456
1234
1
1235
483
877
456
0
1236
483
877
458
0
Drafted below query so far, but not working as expected
select distinct on (ID)
ID,
area,
exch,
line,
ext,
tel_type_cde
from telephone
order by ID,tel_seq_num desc;
Appreciate any help!
try this :
SELECT DISTINCT ON (id, tel_type_cde)
id, area, exch, line, ext, tel_type_cde
FROM telephone
ORDER BY id, tel_type_cde, tel_seq_num DESC ;
You can use the RANK window function with a common table expression to get the expected results
WITH cte AS (
SELECT ID, area, exch, line, ext, tel_type_cde, RANK() OVER (PARTITION BY id, tel_type_cde ORDER BY tel_seq_num DESC) as r
FROM telephone
)
SELECT
ID, area, exch, line, ext, tel_type_cde
FROM cte
WHERE r = 1;
Fiddle

How find duplicates of the same id but different date with SQL (Oracle)

I've got a datatable like that :
id
line
datedt
123
1
01/01/2021
123
2
01/01/2021
123
3
01/01/2021
777
1
13/04/2020
777
2
13/04/2020
123
1
12/04/2021
123
2
12/04/2021
888
1
01/07/2020
888
2
01/07/2020
452
1
05/01/2020
888
1
02/05/2021
888
2
02/05/2021
I'd like to obtain a result like that, ie : the nb of same id with differents dates.
Example we can find 123 with 2 diffents dates, 888 too, but only date for 777 and 452
id
nb
123
2
777
1
888
2
452
1
How could I get that ?
Hope it's clear :)
Thanks you
select id , count(distinct datedt) as nb
from table
group by id

Oracle merge adding records when matched

I have a table that has an ID field with a trigger (so it's essentially an IDENTITY field) as my primary key. I mostly don't care about that.
The rest of the data are several linking keys, and I want to query my data, and if any of those keys have changed, add a new record with a new effective date. If all the keys are the same, then nothing should be added.
However, even when all of the keys match, it is adding new records. All of the fields I care about are exactly the same, so I'm essentially getting duplicate records, but with a new ID and new effective date.
I'll simplify my code a bit, but this is essentially what I have:
MERGE_TABLE (
merge_ID NUMBER(18) PRIMARY KEY NOT NULL,
asof_Date Date,
keyA varchar2(10 byte),
keyB varchar2(10 byte),
keyC varchar2(10 byte),
table_date Date)
There is a trigger on merge_ID on insert to use a sequence.
MERGE INTO merge_table mt
USING (
select keyA, keyB, keyC, table_date
from table -- it's actually a complex query, but it's getting data
) tbl
ON (rtrim(tbl.keyA) = rtrim(mt.keyA)
AND rtrim(tbl.keyB) = rtrim(mt.keyB)
AND rtrim(tbl.keyC) = rtrim(mt.keyC))
WHEN NOT MATCHED THEN
INSERT (asof_Date, keyA, keyB, keyC, table_date)
VALUES (sysdate, tbl.keyA, tbl.keyB, tbl.keyC, tbl.table_date)
If my MERGE_TABLE starts with the following data:
merge_ID asof_Date keyA keyB keyC table_date
10 1/1/2018 333 456 987 12/31/2017
11 1/1/2018 444 234 876 12/31/2017
12 1/1/2018 222 789 654 12/31/2017
then, after running it, I have the following data:
merge_ID asof_Date keyA keyB keyC table_date
10 1/1/2018 333 456 987 12/31/2017
11 1/1/2018 444 234 876 12/31/2017
12 1/1/2018 222 789 654 12/31/2017
13 3/22/2018 333 456 987 12/31/2017
14 3/22/2018 444 234 876 12/31/2017
15 3/22/2018 222 789 654 12/31/2017
My keys all matched, but it did an insert anyway. Why?
If KeyB had changed on the first record from 456 to 678, the data I would want is:
merge_ID asof_Date keyA keyB keyC table_date
10 1/1/2018 333 456 987 12/31/2017
11 1/1/2018 444 234 876 12/31/2017
12 1/1/2018 222 789 654 12/31/2017
13 3/22/2018 333 678 987 12/31/2017

Select records for batch processing in loop

I need to select the records in batch wise, like in below example we have 20 records. if I give batch of size of 10 there would be two loops. the problem here is if I do top 10 then 555 value will be split as its position is 10 and 11. hence 555 should also include in that top first batch. how I can achieve this? this is just example, I have 900 million records to process and my batch will be 2 million in real scenario.
ID
-------
111
111
111
222
222
333
333
444
444
555
555
666
666
777
777
888
888
You can use top with ties - this might return more records then stated but will not break similar ids to different batches:
Create and populate sample table (Please save us this step in your future questions):
DECLARE #T AS TABLE
(ID int)
INSERT INTO #T VALUES
(111),(111),(111),
(222),(222),
(333),(333),
(444),(444),
(555),(555),
(666),(666),
(777),(777),
(888),(888)
The select statement:
SELECT TOP 10 WITH TIES ID
FROM #T
ORDER BY ID
Results:
row ID
1 111
2 111
3 111
4 222
5 222
6 333
7 333
8 444
9 444
10 555
11 555
While selecting the records, you can group them by id prior to limiting their number.

How to get a result for the below table using teradata

I am new to Teradata. I have created the table with empno, mobile and office no as follows. I need mobile and office no in separate column.
empno mobile office
111 9999 4444
222 null 3333
333 5555 7896
444 6666 null
I need to have output as:
111 9999
111 4444
222 3333
333 5555
333 7896
444 6666
SELECT empno, mobile FROM t WHERE mobile IS NOT NULL
UNION ALL
SELECT empno, office FROM t WHERE office IS NOT NULL
ORDER BY empno;
This is not Teradata-specific, works for any SQL database.