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

如何最好地使用SQL查找匹配多个WHERE子句的公共ID,sql,Sql,因此,我刚刚开始学习SQL,并遇到了以下问题。假设我有一个包含3列的表,如下所示: ID | Property_Name | Property_Value 1 | Color | "Blue" 1 | Size | "Large" 2 | Color | "Red" 3 | Color | "Orange" 3 | Size | "

因此,我刚刚开始学习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" ... 谢谢:)

编辑:忘记将preformat标记添加到示例表文本中。就这么做了。

自我连接怎么样

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'

这里是一个

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

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
这是“集合中的集合”子查询的一个示例。我认为最通用的方法是使用聚合,并使用
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;
如果需要这三个条件中的任何一个,则可以使用

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;

这是一个奇怪的结构。奇怪的是,为什么“大小”和“颜色”不只是数据表上的列呢?从你的出发点来看,这看起来正是我应该做的。如果项目规模显著扩大,我会考虑是否将不同的属性合并到一个表中。最好使用不同的表将
大小
颜色
分开。您使用的是什么数据库管理系统?SQL Server?在我看来,糟糕的表设计。颜色和大小应该是单个表上的列。不幸的是,我没有数据库设计的权限。我现在正在使用DbVisualizer来运行SQL查询。我认为这是最简单的答案@goparkyourcar:不过,正如我之前的评论所暗示的,我怀疑这不是存储和搜索数据的最佳方式。这些“属性”中有很多可能/应该只是数据表中的列。看起来这个解决方案很有效。这个查询和我的原始查询在一个包含3500行的表上执行的时间大致相同。然而,这一点看起来更容易理解。非常感谢。
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;