2

我在 Oracle DB 中有下表。

ID  VALUE
-----------
1   1  
1   2  
1   3   
2   1   
2   2  
3   1  
3   2  
3   3  
4   1

如何选择具有所有 3 个值 (1,2,3) 的 ID

4

5 回答 5

5

最简单的选择通常是这样的

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2    select 1 id, 1 val from dual union all
  3    select 1 id, 2 val from dual union all
  4    select 1 id, 3 val from dual union all
  5    select 2 id, 1 val from dual union all
  6    select 2 id, 2 val from dual union all
  7    select 3 id, 1 val from dual union all
  8    select 3 id, 2 val from dual union all
  9    select 3 id, 3 val from dual union all
 10    select 4 id, 1 val from dual
 11  )
 12  select id
 13    from x
 14   where val in (1,2,3)
 15   group by id
 16* having count(distinct val) = 3
SQL> /

        ID
----------
         1
         3

WHERE子句标识您感兴趣的值。该HAVING子句告诉您需要存在多少这些值。例如,如果您希望所有行至少具有 3 个值中的 2 个,您可以更改HAVING子句以查找COUNT2 的 a。

如果一个特定val的保证每个 最多出现一次id,您可以消除子句distinct中的。HAVING

于 2012-07-27T04:49:02.620 回答
2

尝试这个:

SELECT ID
  FROM TABLENAME T
 WHERE EXISTS (SELECT *
                 FROM TABLENAME T1
                WHERE T1.ID = T.ID AND T1.VALUE = '1')
   AND EXISTS (SELECT *
                 FROM TABLENAME T2
                WHERE T1.ID = T.ID AND T2.VALUE = '2')
   AND EXISTS (SELECT *
                 FROM TABLENAME T3
                WHERE T1.ID = T.ID AND T2.VALUE = '3')

或者

SELECT ID
  FROM TABLENAME T
 WHERE (SELECT COUNT( * )
          FROM (SELECT VALUE
                  FROM TABLENAME T1
                 WHERE T1.ID = T.ID
                GROUP BY VALUE)) = 3;

其中 3 是可以通过 a 计算的值的数量

        SELECT COUNT( * )
          FROM TABLENAME T1
        GROUP BY VALUE

所以这将是通用的:

SELECT ID
  FROM TABLENAME T
 WHERE (SELECT COUNT( * )
          FROM (SELECT VALUE
                  FROM TABLENAME T1
                 WHERE T1.ID = T.ID
                GROUP BY VALUE)) = (SELECT COUNT( * )
                                      FROM TABLENAME T2
                                    GROUP BY VALUE)
于 2012-07-27T03:47:29.087 回答
1

select id from (select id,sum(case when value=1 then 1 else 0 end) as 'v1',
sum(case when value=2 then 1 else 0 end) as 'v2',
sum(case when value=3然后 1 else 0 end) as 'v3'
from orac group by id) as final
where v1>0 and v2>0 and v3>0

于 2012-07-27T04:33:27.880 回答
1

这是一个选项... HAVING 子句中的每个表达式都在计算找到等于 1、2 或 3 的值的数量。如果这些计数中的任何一个小于 1,则不会返回 ID。

http://sqlfiddle.com/#!4/00fdc/8

SELECT ID
FROM myTable
GROUP BY ID
HAVING
  SUM(DECODE(VALUE, 1, 1, 0)) > 0 AND
  SUM(DECODE(VALUE, 2, 1, 0)) > 0 AND
  SUM(DECODE(VALUE, 3, 1, 0)) > 0

编辑- 要求值为 1,以及 2 或 3:

SELECT ID
FROM myTable
GROUP BY ID
HAVING
  SUM(DECODE(VALUE, 1, 1, 0)) > 0 AND
  (
      SUM(DECODE(VALUE, 2, 1, 0)) > 0 OR
      SUM(DECODE(VALUE, 3, 1, 0)) > 0
  )
于 2012-07-27T03:52:44.370 回答
1

使用此选项,您将获得更多的 ID,直到您的应用程序选择您想要的列:

SELECT ID,
  sum(CASE WHEN VALUE = 1 THEN 1 ELSE 0 END) AS ONE,
  sum(CASE WHEN VALUE = 2 THEN 1 ELSE 0 END) AS TWO,
  sum(CASE WHEN VALUE = 3 THEN 1 ELSE 0 END) AS THREE
FROM MYTABLE
  GROUP BY ID
  HAVING ONE >= 1 AND TWO >= 1 AND THREE >= 1;

或者,如果您的情况是特定的(只有值 1、2、3 是可能的,并且不允许重复值),那么您可以尝试以下一种:

SELECT ID,
  count(VALUE) AS VALUECOUNT
FROM MYTABLE
  GROUP BY ID
  HAVING VALUECOUNT = 3;

在这样做之前我会小心,因为如果以后你想添加额外的值,你可能会得到副作用。但是,如果您当前的案例符合上述限制,仍然值得提出。

当然,如果您不喜欢获取这些中间计数的想法,请将我给出的查询包含在另一个选择中

SELECT ID FROM (
  ...
)
于 2012-07-27T04:37:28.543 回答