I have a sample table as follows.
A B C D
------+---------+--------+---------
3.2 | India | 456 | 3.2
3.2 | India | -67 | 5
-3.2 | US | -30 | 8
3.2 | UK | 3.9 | 5
5 | UAE | 2.4 | 9
6 | UAE | 5 | -3.2
I would like to first sort the data as shown in the below format. 'B' & 'C' columns are tied to 'D' column such that when I sort 'D' then 'B' & 'C' columns will move accordingly. But 'A' is independent
A(ascending) B C D((Descending))
------------+-----------+--------+--------
-3.2 | UAE | 2.4 | 9
3.2 | US | -30 | 8
3.2 | India | -67 | 5
3.2 | UK | 3.9 | 5
5 | India | 456 | 3.2
6 | UAE | 5 | -3.2
For the table above I would like to get the following as final output (I am ignoring the signs while comparing). In the above table I am Checking 'D' column value in 'A' column(One to One mapping) if it is not their then it should push it down
A(ascending) B C D((Descending))
------------+-----------+--------+--------
-3.2 | India | 456 | 3.2
3.2 | UAE | 5 | -3.2
3.2 | null | null | null
3.2 | null | null | null
5 | India | -67 | 5
6 | null | null | null
null | UAE | 2.4 | 9
null | US | -30 | 8
null | UK | 3.9 | 5
FINAL OUTPUT (Values which are pushed down):
null | UAE | 2.4 | 9
null | US | -30 | 8
null | UK | 3.9 | 5
It's probably using NOT IN
, COUNT
and a JOIN
but I can't seem to put it together properly (especially since I'm selecting data from the same table). Does any one have an idea about this? Thanks.
The following is a total guess, because there isn't enough information in your question to fully understand the join between the a and d columns that you're expecting. I've taken my best guess at it, but if the following is not correct, you'll either have to amend it as appropriate for your logic, or update your question with the correct logic.
with sample_data as (select 3.2 a, 'India' b, 456 c, 3.2 d from dual union all
select 3.2 a, 'India' b, -67 c, 5 d from dual union all
select -3.2 a, 'US' b, -30 c, 8 d from dual union all
select 3.2 a, 'UK' b, 3.9 c, 5 d from dual union all
select 5 a, 'UAE' b, 2.4 c, 9 d from dual union all
select 6 a, 'UAE' b, 5 c, -3.2 d from dual),
-- end of the "sample_data" subquery mimicking your table with data in it
sd1 as (select row_number() over (order by a) rn,
a
from sample_data),
sd2 as (select row_number() over (order by d desc, b, c) rn,
b,
c,
d
from sample_data),
sd3 as (select sd1.a,
sd2.b,
sd2.c,
sd2.d
from sd1
inner join sd2 on (sd1.rn = sd2.rn))
select case when sd5.a is not null and sd4.a is not null then sd4.a
when sd5.a is not null then null
else sd4.a
end a,
case when sd5.b is not null and row_number() over (partition by sd5.a, sd5.b, sd5.c, sd5.d order by sd4.d desc) = 1 then sd5.b
else null
end b,
case when sd5.c is not null and row_number() over (partition by sd5.a, sd5.b, sd5.c, sd5.d order by sd4.d desc) = 1 then sd5.c
else null
end c,
case when sd5.d is not null and row_number() over (partition by sd5.a, sd5.b, sd5.c, sd5.d order by sd4.d desc) = 1 then sd5.d
else null
end d
from sd3 sd4
full outer join sd3 sd5 on (sd4.a = sd5.d)
order by case when a is not null then 1 else 2 end,
a;
A B C D
---------- ----- ---------- ----------
-3.2 UAE 5 -3.2
3.2 India 456 3.2
3.2
3.2
5 UK 3.9 5
5 India -67 5
6
UAE 2.4 9
US -30 8
After the additional information you provided, how about something like:
with sample_data as (select 3.2 a, 'India' b, 456 c, 3.2 d from dual union all
select 3.2 a, 'India' b, -67 c, 5 d from dual union all
select -3.2 a, 'US' b, -30 c, 8 d from dual union all
select 3.2 a, 'UK' b, 3.9 c, 5 d from dual union all
select 5 a, 'UAE' b, 2.4 c, 9 d from dual union all
select 6 a, 'UAE' b, 5 c, -3.2 d from dual),
-- end of the "sample_data" subquery mimicking your table with data in it
sd1 as (select row_number() over (order by a) rn,
a
from sample_data),
sd2 as (select row_number() over (order by d desc, b, c) rn,
b,
c,
d
from sample_data),
sd3 as (select sd1.a,
sd2.b,
sd2.c,
sd2.d,
row_number() over (partition by sd2.d order by sd1.a) rnd,
row_number() over (partition by sd1.a order by sd2.d) rna
from sd1
inner join sd2 on (sd1.rn = sd2.rn))
select case when sd5.a is not null and sd4.a is not null then sd4.a
when sd5.a is not null then null
else sd4.a
end a,
case when sd5.b is not null then sd5.b
else null
end b,
case when sd5.c is not null then sd5.c
else null
end c,
case when sd5.d is not null then sd5.d
else null
end d
from sd3 sd4
full outer join sd3 sd5 on (sd4.a = sd5.d and sd4.rna = sd5.rnd)
order by case when a is not null then 1 else 2 end,
a,
d;
A B C D
---------- ----- ---------- ----------
-3.2 UAE 5 -3.2
3.2 India 456 3.2
3.2
3.2
5 India -67 5
6
UK 3.9 5
US -30 8
UAE 2.4 9
Depending on whether you really don't care about the sign of the values in the a and d columns, you may wish to use abs()
in all the relevant places in the above query.
Also, storing values in a column that aren't related to the rest of the row is usually indicative of bad design. Why is your data stored like that?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.