我今天感觉很愚蠢,但我有一个我想写的查询,但我感觉它可能超出了我的范围。
为了简单起见,我会尝试简化问题。
我有一张这样的表
[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
我需要为所有共享同一类的人获取所有记录(实际记录未分组),但有以下限制:
只有Jen,Jack&约翰共享同一个班级(只有那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包含在原始查询中,但我更喜欢这种方式以便于阅读。
不确定这是否是确切的答案,但我正在寻找的查询使用这种风格,我尝试使用相同的方法编写简单的方法,对于像我一样卡住的人。
答案 0 :(得分:2)
如果您在三个人共享同一课程的课程之后,即使有其他人参加,那么您的查询非常接近,除非您错过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
子句,这意味着您必须在外部查询中进行过滤。希望你能看到我的查询与你的查询相似吗?