How to get the following output? - sql

How to get the following output ?
Input:
t1
-----------------
col1 col2
----------------
2 a
1 c
3 b
----------------
Output:
t1
-----------------
col1 col2
----------------
1 a
2 b
3 c
----------------

You can try using row number like:
SELECT row_number() OVER (ORDER BY a.col2) as col1, col2
FROM t1 a ORDER BY a.col2

select C1.col1, C2.col2
from
(select col1, row_number() over (order by col1) rn
from t1) C1
join
(select col2, row_number() over (order by col2) rn
from t1) C2
on C1.rn=C2.rn
order by C1.rn

I think following query may help you.
SELECT * FROM t1 ORDER BY col1 ;
please check this link for more practice
http://www.sqlfiddle.com/#!3/2e3e9/1/0

Try this..
select col1,col2 from
(select col1,rownum rn from(select col1 from t1 order by col1)) a,
(select col2,rownum rn from(select col2 from t1 order by col2)) b
where a.rn=b.rn

Related

Select columns from different tables without repeating rows

For this example tables:
Table A:
Col1 Col2
-----------
2015 A
2015 B
2015 C
Table B:
Col1 Col2
------------
2015 X
2015 Y
2015 Z
I want a query that returns:
Col1 Col2
------------
A X
B Y
C Z
I have tried something like this:
SELECT TA.COL2, TB.COL2
FROM
(SELECT * FROM TABLE_A WHERE COL1=2015) TA,
(SELECT * FROM TABLE_B WHERE COL1=2015) TB,
But I'm getting duplicated results
Col1 Col2
-----------
A X
A Y
A Z
B X
B Y
B Z
C X
C Y
C Z
A way to do it is to use the row number:
SELECT TA.COL2, TB.COL2
FROM
(SELECT TABLE_A.COL2, ROWNUM AS R1 FROM TABLE_A WHERE COL1=2015) TA,
(SELECT TABLE_B.COL2, ROWNUM AS R2 FROM TABLE_B WHERE COL1=2015) TB,
WHERE T1.R1 = T2.R2
In a SELECT statement, include DISTINCT or DISTINCTROW keyword after the SELECT clause.
For More Details:
http://www.geeksengine.com/database/basic-select/eliminate-duplicate-rows.php
Not sure why you want this but here is my method for doing it.
SELECT
TA.COL2 AS Col1,
TB.COL2 AS Col2
FROM
(SELECT COL1, COL2, ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2) AS Seq FROM TABLE_A) TA
JOIN
(SELECT COL1, COL2, ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2) AS Seq FROM TABLE_B) TB
ON TA.COL1 = TB.COL1
AND TA.Seq = TB.Seq
A union all/group by approach may be what you want:
SELECT MAX(COL2_a) as COL2_a, MAX(COL2_B) as COL2_B
FROM ((SELECT COL2 as COL2_A, NULL as COL2_B,
ROW_NUMBER() OVER (ORDER BY COL2) as seqnum
FROM TABLE_A
WHERE COL1 = 2015
) UNION ALL
(SELECT NULL, COL2, ROW_NUMBER() OVER (ORDER BY COL2) as seqnum
FROM TABLE_B
WHERE COL1 = 2015
) UNION ALL
) t
GROUP BY seqnum;
Alternatively, use a FULL JOIN:
SELECT a.COL2 as COL2_a, b.COL2 as COL2_B
FROM (SELECT a.*,
ROW_NUMBER() OVER (ORDER BY COL2) as seqnum
FROM TABLE_A a
WHERE COL1 = 2015
) a FULL JOIN
(SELECT b.*,
ROW_NUMBER() OVER (ORDER BY COL2) as seqnum
FROM TABLE_B b
WHERE COL1 = 2015
) b
ON a.seqnum = b.seqnum;
Both these methods returns all values, if one table has more values than the other.

If two rows have same id but different col2, how can you keep only the ones that have max col3?

I have a table with three columns (id, col2, col3, col4) where col2 is A or B and col3 and col4 are integers. My problem is, there are many columns that have the same id and a different col2 value, and I want to select ONLY the rows that have a maximum value in col3.
For instance, if we have:
id | col2 | col3 | col4
1 | A | 3 | 2
1 | B | 5 | 3
2 | A | 6 | 2
...
I want to keep only the tuple (1, B, 5, 3). How can I achieve this?
I've tried this:
SELECT id, col2, MAX(col3), col4 FROM t GROUP BY id;
but I get an error saying that this is not a valid GROUP BY statement.
You can use keep:
SELECT id,
MAX(col2) KEEP (DENSE_RANK FIRST ORDER BY col3 DESC) as col2
MAX(col3),
MAX(col4) KEEP (DENSE_RANK FIRST ORDER BY col3 DESC) as col4
FROM t
GROUP BY id;
Or:
SELECT id, col2, col3, col4
FROM (SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY col3 DESC) as seqnum
FROM t
) t
WHERE seqnum = 1;
This query:
select t.*
from tablename t inner join (
select id, max(col3) col3
from tablename
group by id
having count(distinct col2) > 1
) g on g.id = t.id and g.col3 = t.col3
returns for each id that has different values in col2 only 1 row: the one containing the maximum value of col3.
If you also want the other rows where each id does not have different values in col2, then use UNION ALL:
select t.*
from tablename t inner join (
select id, max(col3) col3
from tablename
group by id
having count(distinct col2) > 1
) g on g.id = t.id and g.col3 = t.col3
union all
select t.* from tablename t
where not exists (
select 1 from tablename
where id = t.id and col2 <> t.col2
)
select * from TableName where col3 = (select max(col3) from TableName)

SQL Server : get max of the column2 and column3 value must be 1

I have an output of some part of my stored proedure like this:
col1 col2 col3 col4
--------------------------
2016-05-05 1 2 2
2016-05-05 1 3 32
2016-05-12 2 1 11
2016-05-12 3 1 31
Now I need to get result based on this condition
col2 = 1 and col3 = max or col3 = 1
and col2 = max
The final result should be
col1 col2 col3 col4
-------------------------
2016-05-05 1 3 32
2016-05-12 3 1 31
Not sure if thats the most efficient way , but you can use ROW_NUMBER() :
SELECT * FROM (
SELECT t.*,
ROW_NUMBER() OVER(PARTITION BY t.col1 ORDER BY t.col3 DESC) as rnk,
WHERE t.col2 = 1
UNION ALL
SELECT t.*,
ROW_NUMBER() OVER(PARTITION BY t.col1 ORDER BY t.col2 DESC) as rnk,
WHERE t.col3 = 1) tt
WHERE rnk = 1
This will give you all the records with
(col2=1 and col3=max) or (col3=1 and col2=max)
This is a bit tricky. Your data has no ambiguities, such as duplicate maximuma in col4 or "1" values in both col2 and col3.
The following is a direct translation of the logic in your question:
select t.*
from t
where t.col4 = (select max(t2.col4)
from t t2
where t2.col1 = t.col1 and (t2.col2 = 1 or t2.col3 = 1)
);
Try this. Note if there are more than 1 same max value, then you need all of those in output. And it will work for all scenarios, even when col1 is not in sync with col2 and col3.
I am first finding highest values of col2 and col3 and assigning them value as 1. Then in outer query, I am using your join condition. Demo created for Postgres DB as SQLServer wasn't available.
SQLFiddle Demo
select col1,col2,col3,col4
from
(
select t.*,
RANK() OVER(ORDER BY col3 DESC) as col3_max,
RANK() OVER(ORDER BY col2 DESC) as col2_max
from your_table t
) t1
where
(col2=1 and col3_max=1)
OR
(col3=1 and col2_max=1)
Alternative way:
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY iif(col2 = 1, col3, col2) DESC) as r
FROM tbl) t
WHERE r = 1

Combine multiple tables in one

If I have tlb1 as :
col1
1
2
3
Now I have tlb2 as:
col2 col3
4 Four
5 Five
6 SIX
No I have tlb3 as
col4 col5
sample14 sample15
sample24 sample25
sample34 sample35
What can be the query if I want result as :
col1 col2 col3 col4 col5
1 4 Four sample14 sample15
2 5 Five sample24 sample25
3 6 Six sample34 sample35
I tried with :
select ( (select * from tlb1), (select * from tlb2),(select * from tlb3)) T
But this failed.
Please help me.
with t1 as (select col1, row_number() over (order by col1) rn from tbl1 ),
t2 as (select col2,col3, row_number() over (order by col2) rn from tbl2),
t3 as ( select col4,col5, row_number() over (order by col4) rn from tbl3)
select t1.col1,t2.col2,t2.col3,t3.col4,t3.col5
from t1 full outer join t2 on t1.rn = t2.rn
t3 full outerjoin t2 on t2.rn = t3.rn
try something like this...

column to row for only one column

I have only one column in my table having all distinct values I need to group it into pairs of 3 and make 3 columns out of 3 rows please help
Source
COL1
-----
A
B
C
D
E
F
Required output 1:
COL1
------
A,B,C
D,E,F
Required output 2:
col1 col2 col3
---- ---- ----
A B C
D E F
Output 1:
select listagg(col1, ',') within group (order by col1) as col
from (
select col1,
case
when row_number() over (order by col1) <= (count(*) over ()) / 2 then 0
else 1
end as grp
from foo
)
group by grp
order by grp;
For Output 2:
select max(col1) as col1,
max(col2) as col2,
max(col3) as col3
from (
select case mod(row_number() over (order by col1),3)
when 1 then col1
else null
end as col1,
case mod(row_number() over (order by col1),3)
when 2 then col1
else null
end as col2,
case mod(row_number() over (order by col1),3)
when 0 then col1
else null
end as col3,
case
when row_number() over (order by col1) <= (count(*) over ()) / 2 then 0
else 1
end as grp
from foo
)
group by grp
order by grp;
SQLFiddle example: http://sqlfiddle.com/#!4/d699c/1
Please try below query for second solution:
select Col1, Col2, Col3 From(
select
ceil(row_number() over(order by Col1)/3) Rnum,
mod(row_number() over(order by Col1)+2, 3)+1 Row_Num,
COl1
from
YourTable
)x pivot (min(Col1) for Row_Num in ('1' as Col1, '2' as Col2, '3' as Col3));
Fiddle Demo
Another way (will work for every multiple of 3 of records)
output1
select listagg(col1, ',') within group (order by col1) col1
from
(select col1, row_number() over(order by col1) rn
from t) tt
group by rn - decode(mod (rn, 3) ,0,3,mod (rn, 3));
output2
select c2_col col1, c3_col col2, c1_col col3
from
(select rn - decode(mod (rn, 3) ,0,3,mod (rn, 3)) grp, mod(rn, 3) rnm, col1
from
(select col1, row_number() over(order by col1) rn
from t)) tt
pivot
(
max(col1) as col
for rnm in (0 as c1,1 c2,2 c3)
);
Here is a sqlfiddle demo