根据同一列

时间:2016-08-23 15:15:44

标签: sql sql-server sql-server-2008

很难用文字描述我想要的东西,所以这里是我正在处理的表格

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.我无法更改数据结构,因为它是专有的。感谢您提供任何帮助/建议。

2 个答案:

答案 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