可以写这个查询吗——我错过了什么?

Can this query be written - what am I missing?

我今天感觉很蠢,但我想写一个查询,但我感觉它可能超出我的能力范围。

为了简单起见,我会尽量简化问题。

我有一个table这样的

[Table A]
ID | Class | Name
0      A     Sarah
1      B     Tom
2      C     Bob
3      A     Jen
4      A     John
5      A     Jack
6      B     Name1
7      B     Jack
8      B     Bob

我需要获取共享相同 class 的所有人的所有记录(未分组的实际记录),但有以下限制:

只给我 Jen、Jack 和 John 共享相同 class 的记录(只有这 3 个,没有其他人也没有重复)。

这意味着记录将以 3 组的形式出现。

所以在上面的例子中我会得到

3      A     Jen
4      A     John
5      A     Jack

到目前为止我得到了:

SELECT Class, Name, COUNT(*)
FROM TableA
GROUP BY Class, Name
HAVING COUNT(*) = 3

但除了这不能正常工作之外,我无法指定记录必须包含名称 Jen、Jack 和 John,而不是其他名称。

编辑: 我能够使用内部查询来做到这一点,但它有点慢..如果有人知道更好的方法,请告诉我:

SELECT ....
FROM TableA t1
join TableA  t2 on t1.class = t2.class
WHERE t1.name = 'Jen' AND t2.name = 'John'
AND t1.class IN(SELECT class FROM TableA t3 WHERE t3.name = 'Jack'))) 

我可能已经将 t3 包含在原始查询中,但我更喜欢这种方式以提高可读性。

不确定这是否是准确的答案,但我正在寻找的查询使用这种风格工作,我尝试使用相同的方法为像我一样卡住的任何人编写简单的答案。

如果你在 classes 之后你的三个人都共享相同的 class,即使有其他人参加,那么你的查询非常接近,除了你缺少 WHERE 子句以将行限制为您感兴趣的名称。

此外,如果您不想折叠行 ("the actual records, not grouped by"),那么您需要的是分析 COUNT,而不是聚合。

因此,您所追求的应该类似于:

WITH table_a AS (SELECT 0 ID, 'A' CLASS, 'Sarah' NAME FROM dual UNION ALL
                 SELECT 1 ID, 'B' CLASS, 'Tom' NAME FROM dual UNION ALL
                 SELECT 2 ID, 'C' CLASS, 'Bob' NAME FROM dual UNION ALL
                 SELECT 3 ID, 'A' CLASS, 'Jen' NAME FROM dual UNION ALL
                 SELECT 4 ID, 'A' CLASS, 'John' NAME FROM dual UNION ALL
                 SELECT 5 ID, 'A' CLASS, 'Jack' NAME FROM dual UNION ALL
                 SELECT 6 ID, 'B' CLASS, 'Name1' NAME FROM dual UNION ALL
                 SELECT 7 ID, 'B' CLASS, 'Jack' NAME FROM dual UNION ALL
                 SELECT 8 ID, 'B' CLASS, 'Bob' NAME FROM dual)
-- End of mimicking your table_a with data in it
-- See query below:
SELECT ID,
       CLASS,
       NAME
FROM   (SELECT ID,
               CLASS,
               NAME,
               COUNT(NAME) OVER (PARTITION BY CLASS) name_cnt
        FROM   table_a
        WHERE  NAME IN ('Jen', 'Jack', 'John'))
WHERE  name_cnt = 3;

您会注意到,分析函数没有聚合函数具有的等效 HAVING 子句,这意味着您必须在外部查询中进行过滤。不过,希望您能看到我的查询与您的相似吗?