在组内进行比较以获取公共值

时间:2013-01-24 13:22:08

标签: sql oracle

我有一张包含以下数据的表格

案例1:

table1
-------------
id      type
-------------
1         X
1         Y
2         X
3         Z
3         X
-------------

现在你看到X对于所有id都是通用的,所以在这种情况下我需要返回X

案例2:

table1
-------------
id      type
-------------
1         X
1         Y
2         X
2         Y
3         X
3         Y
--------------

在这种情况下,X和Y都是常见的,那么我需要同时返回X和Y逗号分隔(X,y)

案例3

table1
-------------
id      type
-------------
1         X
1         Y
2         X
2         Y
3         X
3         Y
4         NULL
------------------

如果null到达任何记录,我需要返回NULL

实际上,我已经说过的数据来自3个表,所以我已经为此编写了查询,但现在我需要比较组内公共数据的组,这让我感到困惑,如何比较各组?

注意:此群组基于ID

任何帮助都是适当的

1 个答案:

答案 0 :(得分:1)

你可以计算出与ID的数量相比的出现次数吗?

with data as (select rownum id, 'X' type from dual connect by level <= 3
              union all
              select rownum id, 'Y' type from dual connect by level <= 3
              union all
              select 3 id, 'Z' type from dual)
select wm_concat(distinct type)
  from (select type, count(*) over (partition by type) cnt, count(distinct id) over () total_ids
          from data)
 where cnt = total_ids;

在11g中你当然有LISTAGG而不是WM_CONCAT。如果对于每个ID,多次出现相同的type,您可以将count(*) over (partition by type)更改为count(distinct id) over (partition by type)

编辑:

如果你有

3, Z
3, NULL 

(而不是4,NULL)并且还希望在这种情况下返回NULL而不是分隔列表然后你可以添加一个检查(使用4,上面的NULL将返回null,即使在先前的SQL版本上也是如此这些数字不会占上风:)

       with data as (select rownum id, 'X' type from dual connect by level <= 3
                      union all
                      select rownum id, 'Y' type from dual connect by level <= 3
                      union all
                      select 3 id, 'Z' type from dual)
        select wm_concat(distinct type)
          from (select type, count(*) over (partition by type) cnt, count(distinct id) over 

() total_ids,
                       max(case when type is null then 'Y' else 'N' end) over () has_null_in_set
                  from data)
         where cnt = total_ids
          and has_null_in_set = 'N';