如何最好地使用SQL来查找与多个WHERE子句匹配的公共ID

时间:2013-08-15 20:47:38

标签: sql

所以我刚开始学习SQL,并遇到了以下问题。假设我有一个包含3列的表,如下所示:

ID    | Property_Name    | Property_Value
1     | Color            | "Blue"
1     | Size             | "Large"
2     | Color            | "Red"
3     | Color            | "Orange"
3     | Size             | "Small"
4     | Color            | "Blue"
4     | Size             | "Large"
...

现在,假设我想找到具有Color = Blue和Size = Large(又名.ID 1和4)的ID, 我怎么做到最好呢。我提出的最好的方法是以下,但它看起来很笨拙......

SELECT ID FROM PropertyTable
WHERE
ID IN (
        SELECT ID FROM PropertyTable WHERE
        Property_Name='Color' AND Property_Value='blue' )
AND
(Property_Name='Size' AND Property_Value='Large')

谢谢:)

编辑:忘记将预格式标签添加到示例表文本中。刚刚这样做了。

3 个答案:

答案 0 :(得分:6)

自我加入怎么样?

SELECT T1.ID
FROM PropertyTable T1
JOIN PropertyTable T2 ON T1.ID = T2.ID
WHERE
        T1.PropertyName = 'Color' AND T1.PropertyValue = 'Blue'
    AND
        T2.PropertyName = 'Size' AND T2.PropertyValue = 'Large'

这是SQLFiddle

答案 1 :(得分:0)

如果颜色和大小的值不重叠,那么你可以这样做。

SELECT
 ID
FROM PropertyTable
WHERE Property_Name IN ('Color','Size') 
 AND Property_Value IN ('Blue','Large')
GROUP BY
 ID
HAVING 
 COUNT(ID) = 2

如果他们确实重叠,那就试试吧。

SELECT
 ID
FROM PropertyTable
WHERE (Property_Name = 'Color' AND Property_Value = 'Blue')
 OR (Property_Name = 'Size' AND Property_Value = 'Large')
GROUP BY
 ID
HAVING 
 COUNT(ID) = 2

答案 2 :(得分:0)

这是“set-within-sets”子查询的示例。我认为最常用的方法是使用带有having子句的聚合:

select ID
from PropertyTable pt
group by ID
having sum(case when Property_Name='Color' AND Property_Value='blue' then 1 else 0 end) > 0 and
       sum(case when Property_Name='Size' AND Property_Value='Large' then 1 else 0 end) > 0;

having语句的每个子句都计算与每个条件匹配的行数。

我喜欢这个的原因是因为它很通用如果你想添加另一个属性,你只需添加类似的子句:

select ID
from PropertyTable pt
group by ID
having sum(case when Property_Name='Color' AND Property_Value='blue' then 1 else 0 end) > 0 and
       sum(case when Property_Name='Size' AND Property_Value='Large' then 1 else 0 end) > 0 and
       sum(case when Property_Name = 'Heating' and Property_Value = 'Gas' then 1 else 0 end) > 0;

如果您想要这三个条件中的任何一个,那么您将使用or

select ID
from PropertyTable pt
group by ID
having sum(case when Property_Name='Color' AND Property_Value='blue' then 1 else 0 end) > 0 or
       sum(case when Property_Name='Size' AND Property_Value='Large' then 1 else 0 end) > 0 or
       sum(case when Property_Name = 'Heating' and Property_Value = 'Gas' then 1 else 0 end) > 0;