前言,我不确定这个问题是否有意义。
我有一个看起来像这样的表:
+----------------+-----------+
| ProductGroupID | ProductID |
+----------------+-----------+
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
| 3 | 1 |
| 3 | 2 |
| 4 | 1 |
| 4 | 2 |
| 4 | 3 |
+----------------+-----------+
我要做的是查找包含ProductGroupID
1和2的所有ProductID
。
+----------------+
| ProductGroupID |
+----------------+
| 1 |
| 3 |
| 4 |
+----------------+
下面是我创建的一个天真的脚本,但我认为它可以大大改进。
SELECT DISTINCT ProductGroupID
FROM
(SELECT ProductGroupID FROM tbl WHERE ProductID = 1 ) t1
INNER JOIN
(SELECT ProductGroupID FROM tbl WHERE ProductID = 2 ) t2
ON t1.ProductGroupID = t2.ProductGroupID
出于某种原因,我的直觉告诉我CROSS APPLY
在这种情况下可能有用,但我似乎无法解释这个问题。
任何帮助将不胜感激。
如果您可以生成一个显示ProductGroupID
的脚本,其中只显示1和3,并且忽略4,因为它在集合中有一个额外的项目。
答案 0 :(得分:3)
如何使用HAVING
:
WITH VTE AS(
SELECT *
FROM (VALUES (1,1),
(1,2),
(2,3),
(2,4),
(3,1),
(3,2),
(4,1),
(4,2),
(4,3)) V(ProductGroupID, ProductID))
SELECT ProductGroupID
FROM VTE
GROUP BY ProductGroupID
HAVING COUNT(CASE ProductID WHEN 1 THEN 1 END) >0
AND COUNT(CASE ProductID WHEN 2 THEN 1 END) >0;
如果你想忽略ProductIDGroup
4,那么:
WITH VTE AS(
SELECT *
FROM (VALUES (1,1),
(1,2),
(2,3),
(2,4),
(3,1),
(3,2),
(4,1),
(4,2),
(4,3)) V(ProductGroupID, ProductID))
SELECT ProductGroupID
FROM VTE
GROUP BY ProductGroupID
HAVING COUNT(CASE ProductID WHEN 1 THEN 1 END) >0
AND COUNT(CASE ProductID WHEN 2 THEN 1 END) >0
AND COUNT(CASE WHEN ProductID NOT IN (1,2) THEN 1 END) = 0;