很难用文字描述我想要的东西,所以这里是我正在处理的表格
Persons
First | Last | ID
John | Smith | 1
Jane | Smith | 2
PerKey
ID | KW | HITS
1 | P.E. | 1
1 | M E | 1
1 | HVAC | 4
2 | Acct | 7
我想要做的是从标准符合多行的人中选择。
例如,我想知道谁有'P.E.'和'M E'和'暖通空调'。
在这种情况下会返回John Smith。
我已经能够通过IN和HAVING子句实现这一点,但这限制了我无法过滤个人拥有KW和OR子句的次数。
假设我只想要'暖通空调'上有5次点击的人,那将理想地排除约翰史密斯。这是我的查询:
SELECT first, last
FROM persons
LEFT JOIN perkey ON persons.id = perkey.id
WHERE kw IN ('P.E.','M E','HVAC')
GROUP BY first, last, persons.id
HAVING COUNT(DISTINCT kw) = 3
我正在使用SQL Server 2008.我无法更改数据结构,因为它是专有的。感谢您提供任何帮助/建议。
答案 0 :(得分:3)
您可以使用条件聚合来有选择地计算每个可能的kw
值:
SELECT first, last,
COUNT(CASE WHEN kw = 'P.E.' THEN 1 END) AS PE,
COUNT(CASE WHEN kw = 'M E' THEN 1 END) AS ME,
COUNT(CASE WHEN kw = 'HVAC' THEN 1 END) AS HVAC
FROM persons
LEFT JOIN perkey ON persons.id = perkey.id
WHERE kw IN ('P.E.','M E','HVAC')
GROUP BY first, last, persons.id
HAVING COUNT(DISTINCT kw) = 3
修改强>
如果您想根据HVAC
次出现来过滤记录,那么您可以在HAVING
子句中添加条件聚合,例如:
SELECT first, last
FROM persons
LEFT JOIN perkey ON persons.id = perkey.id
WHERE kw IN ('P.E.','M E','HVAC')
GROUP BY first, last, persons.id
HAVING COUNT(DISTINCT kw) = 3 AND
COUNT(CASE WHEN kw = 'HVAC' THEN 1 END) > 5
<强> EDIT2:强>
如果您想根据hits
字段的值过滤记录,则可以使用:
SELECT first, last
FROM persons
LEFT JOIN perkey ON persons.id = perkey.id
WHERE kw IN ('P.E.','M E','HVAC')
GROUP BY first, last, persons.id
HAVING COUNT(DISTINCT kw) = 3 AND
COUNT(CASE WHEN hits > 4 THEN 1 END) > 0
答案 1 :(得分:2)
条件分组应该有效,既可以检查所有类型的kw,也可以限制或进一步检查任何/所有类型的出现次数。像这样:
SELECT persons.id, first, last,
SUM(CASE WHEN kw = 'P.E.' THEN 1 ELSE 0 END) AS PE,
SUM(CASE WHEN kw = 'M E' THEN 1 ELSE 0 END) AS ME,
SUM(CASE WHEN kw = 'HVAC' THEN 1 ELSE 0 END) AS HVAC
FROM persons
LEFT JOIN perkey ON persons.id = perkey.id
WHERE kw IN ('P.E.','M E','HVAC')
GROUP BY first, last, persons.id
HAVING SUM(CASE WHEN kw = 'P.E.' THEN 1 ELSE 0 END) > 0
AND SUM(CASE WHEN kw = 'M E' THEN 1 ELSE 0 END) > 0
AND SUM(CASE WHEN kw = 'HVAC' THEN 1 ELSE 0 END) > 0