How to convert row to column for below scenario - oracle

iam trying to convert rows to columns in SQL. the below is my data.
id1 id2 id3
---------------
100 101 103
i want to populate output below. could you please help me out.
output:
-----
100
101
103
tried below:
select * from(select value, columnname from test_109)
src
pivot
(value for columnname in(id,id_1,id_2)
)piv;

A simple option is
select id1 from test_109 union all
select id2 from test_109 union all
select id3 from test_109;

You want UNPIVOT (not PIVOT):
SELECT value
FROM test_109
UNPIVOT (value for columnname in(id1,id2,id3));
Which, for the sample data:
CREATE TABLE test_109 (id1, id2, id3) AS
SELECT 100, 101, 103 FROM DUAL;
Outputs:
VALUE
100
101
103
db<>fiddle here

Related

Display the Alternative columns from table row

enter image description here
Display the Alternative columns from table row
Convert the salary column to a string data type (so that salary and name have the same data type) and then UNPIVOT:
Oracle Setup:
CREATE TABLE test_data ( id, name, salary ) AS
SELECT 100, 'A', 1000 FROM DUAL UNION ALL
SELECT 101, 'B', 2000 FROM DUAL UNION ALL
SELECT 102, 'C', 3000 FROM DUAL
Query:
SELECT id, value
FROM (
SELECT id, name, TO_CHAR( salary ) AS salary
FROM test_data
)
UNPIVOT ( value FOR key IN ( name, salary ) )
Output:
ID | VALUE
--: | :----
100 | A
100 | 1000
101 | B
101 | 2000
102 | C
102 | 3000
db<>fiddle here
Alternatively, UNION ALL can also work for you, If you agreed to change the datatype of Salary column -
SELECT ID, Name "Name & Salary"
FROM TABLE1
UNION ALL
SELECT ID, Salary
FROM TABLE1
ORDER BY ID, Name

display multiple column records in one column in oracle

I have Table having following columns in Oracle;
ID NIC NTN MBL NAME
---------------------------------------
1 1234512 ABC
2 321 XYZ
3 5421 POI
4 541245 624
I need to display like this in select query
ID NIC/NTN/MBL NAME
1 1234512 ABC
2 321 XYZ
3 5421 POI
4 541245 // taking first value
I was trying to do with
SELECT
A.ID,
"CNIC/NTN/MBL"
A.NAME,
A.REASON
B.NAME
FROM TABLEA A
INNER JOIN TABLEB B ON A.R_ID = B.R_ID
UNPIVOT INCLUDE NULLS
(
CNIC/NTN/MBL FOR cols IN (A.NIC, A.NTN, A.MBL)
)
but unable to do.
Use COALESCE:
SELECT
ID,
COALESCE(NIC, NTN, MBL) AS "NIC/NTN/MBL",
NAME
FROM yourTable;
This should work because in the call to COALESCE above, I list the three columns from left to right, and the first non NULL value will be retained.
You need the COALESCE function (which simply returns the first non-null value in the specified inputs, reading from left to right), like so:
WITH your_table AS (SELECT 1 ID, 1234512 nic, NULL ntn, NULL mbl, 'ABC' NAME FROM dual UNION ALL
SELECT 2 ID, NULL nic, 321 ntn, NULL mbl, 'ABC' NAME FROM dual UNION ALL
SELECT 3 ID, NULL nic, NULL ntn, 5421 mbl, 'ABC' NAME FROM dual UNION ALL
SELECT 4 ID, 541245 nic, 624 ntn, NULL mbl, 'ABC' NAME FROM dual)
SELECT ID,
COALESCE(nic, ntn, mbl) nic_ntn_mbl,
NAME
FROM your_table;
ID NIC_NTN_MBL NAME
---------- ----------- ----
1 1234512 ABC
2 321 ABC
3 5421 ABC
4 541245 ABC

Oracle Join: getting all values from table 2 for duplicates values in table 1

I hope the title above somewhat makes sense...
So I have one table with some duplicate in it:
Key
100
100
100
101
102
102
103
And a second table with non-duplicate keys and a corresponding indicator:
Key Indicator
100 Y
101 N
102 Y
103 N
How would I do a join so that I get a return of table 1's duplicate Keys and the corresponding Indicator? So that...
Key Indicator
100 Y
100 Y
100 Y
101 N
102 Y
102 Y
103 N
No matter how I join I continue to get duplicates.
Ok so if last table is the desired result, then a simple JOIN has to do the trick:
SELECT tab1.key, tab2.Indicator
FROM table1 tab1
INNER JOIN table2 tab2 ON tab2.key = tab1.key
So that for every key in table1 that has a match in table2, the row from table1 will be presented with indicator of the matched key in table2. Next I present it with the data you originally posted:
select tab1.key, tab2.indicator
from (
select 100 as key from dual
union all
select 100 as key from dual
union all
select 100 as key from dual
union all
select 101 as key from dual
union all
select 102 as key from dual
union all
select 102 as key from dual
union all
select 103 as key from dual ) tab1
inner join ( select 100 as key, 'Y' as indicator from dual
union all
select 101 as key, 'N' as indicator from dual
union all
select 102 as key, 'Y' as indicator from dual
union all
select 103 as key, 'N' as indicator from dual
) tab2 on tab2.key = tab1.key;
With result as:
KEY INDICATOR
--- ---------
100 Y
100 Y
100 Y
101 N
102 Y
102 Y
103 N

Hive - Select unique rows based on some key field

I am using Hive 1.2.1 and want to select unique rows based on empid
empid empname dept
101 aaaa dept1
101 aaaa dept2
102 bbbb dept1
103 cccc dept2
I tried to use correlated subquery but that does not work
select empid,
empname,
dept
(select count(*)
from emp t2
where t2.empid = t1.empid) as row_number
from emp t1 where row_number=1
order by empid;
Is there a way to select unique value based on some key field? Need your help..
Expected output would be
empid empname dept
101 aaaa dept1
102 bbbb dept1
103 cccc dept2
Thanks.
If you need a single row per unique key, than you can use row_number():
select empid, empname, dept from (
select row_number() over (partition by empid order by empname , dept) as rowNum, empid, empname, dept from table
) q where rowNum == 1

Sql Query Problem

i have problem when joining tables(left join)
table1:
id1 amt1
1 100
2 200
3 300
table2:
id2 amt2
1 150
2 250
2 350
my Query:
select id1,amt1,id2,amt2 from table1
left join table2 on table2.id1=table1.id2
my supposed o/p is:
id1 amt1 id2 amt2
row1: 1 100 1 150
row2: 2 200 2 250
row3: 2 200 2 350
i want o/p in row3 as
2 null 2 350
ie i want avoid repetetion of data(amt1)
friends help!
Using LEAD and LAG gives acces to previous or following rows in oracle.
SELECT id1, decode(amt1, lag(amt1) over (order by id1, id2), '', amt1) amt1,
id2, amt2
FROM table1 left join table2 on table2.id1=table1.id2
ORDER BY id1, id2
The order of the query and the order given to the lag function should be the same.
Explanation:
If the current am1 is the same as the preceding amt1 (preceding in the given order) then omit the value.
EDIT
According to your comment, add an additional check for id changes.
SELECT id1,
decode(id1, lag(id1) over (order by id1, id2),
decode(amt1, lag(amt1) over (order by id1, id2), '', amt1),
amt1) amt1,
id2, amt2
FROM table1 left join table2 on table2.id1=table1.id2
ORDER BY id1, id2
Use the same LAG feature to check for id changes. The expression is a bit more complex, but its comparable with a nested if statement.
select distinct id1,amt1,id2,amt2 from table1 left join table2 on table2.id1=table1.id2
try this ?

Resources