简体   繁体   English

通过考虑重复项比较同一表中的两列

[英]Comparing two columns in a same table by considering the duplicates

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. “ B”和“ C”列绑定到“ D”列,这样当我对“ D”进行排序时,“ B”和“ C”列将相应移动。 But 'A' is independent 但是“ A”是独立的

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”列中的“ D”列值(一对一映射),如果不是,则应将其下推

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). 它可能正在使用NOT INCOUNTJOIN但是我似乎无法正确地将它们放在一起(特别是因为我是从同一张表中选择数据)。 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. 以下是一个总的猜测,因为您的问题中没有足够的信息来完全理解您期望的a和d列之间的连接。 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. 根据您是否真的不在乎a和d列中的值的符号,您可能希望在上述查询的所有相关位置使用abs()

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? 为什么您的数据如此存储?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM