Oracle查询以匹配表中所有行的列表中的所有值

时间:2017-03-24 09:11:06

标签: sql oracle

我的表结构如下:

ID    A     B
--   ---  -----
 1    a     a1
 2    b     b1
 3    a     a2
 4    c     a1
 5    b     b2

我想要列A中的这些值,这些值与列表中B的所有值相关。

例如:

我有一份A&#39的名单:

{a1,a2}

输出应为a
c在结果中返回NOT,因为它仅与a1相关,而与a2无关。

有没有办法通过SQL查询获得此结果?

被修改

它应该适用于这种特殊情况:

ID    A     B
--   ---  -----
 1    a     a1
 2    b     b1
 3    a     a2
 4    c     a1
 5    b     b2
 6    c     a3
 7    c     a2

现在c也与a2a3相关,但不应该返回,因为作为结果的一部分,c应该与a1完全相关{ {1}}和a2

但如果我查询如下:

SELECT A
FROM   table_name
WHERE  B IN ( 'a1', 'a2' )      -- The items in the list
GROUP BY A
HAVING COUNT( DISTINCT b ) = 2;

它也会返回c

3 个答案:

答案 0 :(得分:5)

Oracle安装程序

CREATE TABLE table_name ( ID, A, B ) AS
SELECT 1,    'a',     'a1' FROM DUAL UNION ALL
SELECT 2,    'b',     'b1' FROM DUAL UNION ALL
SELECT 3,    'a',     'a2' FROM DUAL UNION ALL
SELECT 4,    'c',     'a1' FROM DUAL UNION ALL
SELECT 5,    'b',     'b2' FROM DUAL;

查询 - 使用GROUP BYCOUNT( DISTINCT ... )

SELECT A
FROM   table_name
WHERE  B IN ( 'a1', 'a2' )      -- The items in the list
GROUP BY A
HAVING COUNT( DISTINCT b ) = 2; -- The number of items in the list

<强>输出

A
-
a

查询 - 动态传递列表

CREATE OR REPLACE TYPE stringlist IS TABLE OF VARCHAR2(10);
/

SELECT A
FROM   table_name
WHERE  B MEMBER OF :your_list
GROUP BY A
HAVING COUNT( DISTINCT B ) = CARDINALITY( :your_list );

绑定变量:your_list的类型为stringlist

如果列表作为分隔字符串传递,那么您可以使用Splitting delimited strings文档页面中的任何技术将其分开。有一个简单的PL/SQL function会将其作为可以插入上述查询的集合返回。

<强>更新

SELECT A
FROM   table_name
GROUP BY A
HAVING COUNT( DISTINCT CASE WHEN b IN ( 'a1', 'a2' )     THEN b END ) = 2
AND    COUNT( DISTINCT CASE WHEN b NOT IN ( 'a1', 'a2' ) THEN b END ) = 0;

SELECT A
FROM   table_name
GROUP BY A
HAVING COUNT( DISTINCT CASE WHEN b MEMBER OF :your_list     THEN b END ) = CARDINALITY( :your_list )
AND    COUNT( DISTINCT CASE WHEN b NOT MEMBER OF :your_list THEN b END ) = 0;

答案 1 :(得分:0)

使用GROUP BYCOUNT

SELECT A
FROM yourtable
WHERE B IN ('a1', 'a2')
GROUP BY A
HAVING Count(DISTINCT B) > 1

答案 2 :(得分:-1)

SELECT DISTINCT A      
FROM tablename   
WHERE B = 'a1'
OR B = 'a2'     

我认为这应该可以解决问题。添加了Distinct,因此A中的值'a'将仅显示一次。