从组中选择满足条件A的行。如果不行,请给我满足条件B的行

时间:2019-04-19 16:56:53

标签: sql oracle

我提出了一个有趣的问题,过去几天一直困扰着我。假设您具有以下数据结构:

Col1 |  Col2    | Col3 | Col4
100  | "Val1"   | 0    | 100
100  | "Val2"   | 1    | null
100  | "Val 3"  | 0    | null
101  |  "Val4"  | 0    | null
101  |  "Val5"  | 1    | null
102  |  "Val6"  | 0    | null

我需要那一行Col4!=null。如果所有行的Col4null,请返回给我一行Col3=1,但是如果Col4null都是Col3=0,则返回我任何一行。

因此上述数据的结果集看起来像

Col1  |  Col2    |  Col3  | Col4
100   |  "Val1"  |   0    |  100
101   |  "Val5"  |   1    | null
102   |  "Val6"  |   0    | null

我知道可以使用分析功能来完成此操作,按Col1Col4Col3对其进行排序,并使用分析功能来获取其中的第一行每个组,但我们正在使用不支持分析功能的内部ORM。

请让我知道是否可以使用简单的SQL(JOIN,Case等)完成。


编辑:

Col4具有非空值的每个组只有一行,而col31的每个组只有一行。而且,组中的一行可以满足Col4而不是nullCol3=1的两个条件。

1 个答案:

答案 0 :(得分:2)

这个怎么样?每个CONDx CTE都会解决一个条件。

  • COND1返回COL4不为空的行
  • COND2返回行COL1COND1结果集中不存在的行,并且COL4的值为NULL(在这种情况下,不同值的计数= 0),并且COL3 = 1
  • COND3就是剩下的一切

最终结果是所有这些元素的并集。

SQL> with test (col1, col2, col3, col4) as
  2    (select 100, 'val1', 0, 100  from dual union all
  3     select 100, 'val2', 1, null from dual union all
  4     select 100, 'val3', 0, null from dual union all
  5     select 101, 'val4', 0, null from dual union all
  6     select 101, 'val5', 1, null from dual union all
  7     select 102, 'val6', 0, null from dual
  8    ),
  9  cond1 as
 10    (select col1, col2, col3, col4
 11     From test
 12     where col4 is not null
 13    ),
 14  cond2 as
 15    (select col1, col2, col3, col4
 16     from test t
 17     where t.col1 not in (select col1 from cond1)
 18       and col1 in (select col1
 19                    from test
 20                    group by col1
 21                    having count(distinct col4) = 0
 22                   )
 23       and col3 = 1
 24    ),
 25  cond3 as
 26    (select col1, col2, col3, col4
 27       from test t
 28       where t.col1 not in (select col1 from cond1
 29                            union all
 30                            select col1 from cond2
 31                           )
 32    )
 33  select col1, col2, col3, col4 from cond1
 34  union all
 35  select col1, col2, col3, col4 from cond2
 36  union all
 37  select col1, col2, col3, col4 from cond3
 38  order by col1;

      COL1 COL2       COL3       COL4
---------- ---- ---------- ----------
       100 val1          0        100
       101 val5          1
       102 val6          0

SQL>