所以我刚开始学习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')
谢谢:)
编辑:忘记将预格式标签添加到示例表文本中。刚刚这样做了。
答案 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'
答案 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;