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

4

我有以下表结构:

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

我希望从A列中获取与B列列表中所有值相关联的值。

例如:

我有一个A列的列表:

{a1,a2}

输出结果应该是a
c不会在结果中返回,因为它只与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必须仅与a1a2相关联。

但是,如果我按如下查询:

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

它也返回c

值列表是如何给出的?它是包含值列表的字符串,查询结果还是其他形式的数据? - Aleksej
3个回答

6

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;

Query - Use GROUP BY and COUNT( 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

如果列表以分隔字符串形式传递,则可以使用拆分分隔符字符串文档页面中的任何技术来分隔它。有一个简单的PL/SQL函数,可以将其返回为集合,然后将其插入上述查询中。

更新:

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;

@MTO 这个可以工作!除了一个情况:我在问题中添加了这个特殊情况。你能看一下吗? - OutOfMind
@OutOfMind,它也适用于您的“特殊情况”。WHERE子句将进行过滤以消除c/a3行,然后HAVING子句将过滤掉c组,因为它只剩下一个不同的值,而不是两个。 - MT0
好的! 还有一个情况想到了我: 如果ca1,a2,a3相关,则会返回它,但根据我的要求,它不应该被返回。 - OutOfMind
太棒了!谢谢! - OutOfMind

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

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

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


即使在原始示例中它没有a2行,这将返回c - MT0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接