Sql 使用AND和OR通过查询检索多行

Sql 使用AND和OR通过查询检索多行,sql,postgresql,postgresql-9.1,relational-division,Sql,Postgresql,Postgresql 9.1,Relational Division,我想使用相同的id检索多行。因此,有了这个表组件_属性,根据下面的SQL查询检查,我希望有两条记录作为结果,id:8和9,但是当然,我什么也没有检索,因为我正在检查cp.property_id=9102和更高版本,并且检查cp.property_id=8801,这同时是不可能的 ID;type_id;name;desc;property_id,value -------------------------------------- 8;3832;"amplifier1";"";8801;"3"

我想使用相同的id检索多行。因此,有了这个表组件_属性,根据下面的SQL查询检查,我希望有两条记录作为结果,id:8和9,但是当然,我什么也没有检索,因为我正在检查cp.property_id=9102和更高版本,并且检查cp.property_id=8801,这同时是不可能的

ID;type_id;name;desc;property_id,value
--------------------------------------
8;3832;"amplifier1";"";8801;"3"
8;3832;"amplifier1";"";9102;"4015"
9;3832;"amplifier2";"";8801;"3"
9;3832;"amplifier2";"";9102;"4016"
这是我目前的查询,没有检索到任何内容

SELECT c.id, c.type_id, cp.property_id, cp.value 
FROM components_component AS c 
INNER JOIN components_componentproperty AS cp 
ON c.id = cp.component_id 
WHERE 
(cp.property_id = 9102  AND cp.value IN ('4015', '4016')) 
OR
(cp.property_id = 8801  AND cp.value = '3') 
AND c.type_id = 3832

component==>component_属性这是关系划分的一种情况:

SELECT c.id, c.name
FROM   components_componentproperty cp1
JOIN   components_componentproperty cp2 USING (component_id)
JOIN   components_component         c   ON c.id = cp1.component_id
WHERE  cp1.property_id = 9102  AND cp1.value IN ('4015', '4016')
AND    cp2.property_id = 8801  AND cp2.value = '3'
AND    c.type_id = 3832
GROUP  BY c.id;
我们在此汇集了大量相关技术:

检查大量属性 您可以展开上面的查询,对于一手完整的属性,它将是最快的解决方案之一。对于更大的数字,走这条路线会更方便,也会更快:

例如,对于5个属性,请根据需要展开:

SELECT c.id, c.name
FROM  (
   SELECT id
   FROM  (
      SELECT component_id AS id, property_id  -- alias id just to shorten syntax
      FROM   components_componentproperty
      WHERE  property_id IN (9102, 8801, 1234, 5678, 9876)  -- expand as needed
      GROUP  BY 1,2
      ) cp1
   GROUP  BY 1
   HAVING count(*) = 5  -- match IN expression
   ) cp2
JOIN   components_component c USING (id);
内部子查询cp1的额外步骤只是必要的,因为很明显,在components\u componentproperty中,每个component\u id、property\u id都有多个条目。我们可以将cp1和cp2合二为一进行检查

HAVING count(DISTINCT property_id) = 5
但我认为这会更昂贵,因为countDISTINCT col每行需要一个排序操作

对于很长的列表,在中是一个糟糕的选择。考虑:


显示您的预期输出也显示从组件提取的结构/样本数据\u组件-我还看到您有c.type\u id=3832可能您的意思是cp.type\u id…@unique\u id uhmmm,我有4条记录,我应该只得到两条记录,它们代表了与属性值匹配的两个组件。如果有更多属性要比较呢。属性是动态的,所以我可以比较2、3或10。@鲁本:我为此添加了一个解决方案。它完成了以下工作:从组件中选择c.id、c.name作为c,其中c.id在从组件中选择组件中,c.id在组件属性中,属性id=9102,值在“4015”中,“4016”和c.id从components\u componentproperty中选择component\u id,其中property\u id=8801和“3”中的值@Ruben:Yes,也应该起作用。使用解释分析测试性能。连接的速度通常比中快。对于存在的许多重复匹配,速度通常更快。简言之:In仅在小范围内具有竞争力。
id;name
-------
8;amplifier1
9;amplifier2
SELECT c.id, c.name
FROM   components_componentproperty cp1
JOIN   components_componentproperty cp2 USING (component_id)
JOIN   components_component         c   ON c.id = cp1.component_id
WHERE  cp1.property_id = 9102  AND cp1.value IN ('4015', '4016')
AND    cp2.property_id = 8801  AND cp2.value = '3'
AND    c.type_id = 3832
GROUP  BY c.id;
SELECT c.id, c.name
FROM  (
   SELECT id
   FROM  (
      SELECT component_id AS id, property_id  -- alias id just to shorten syntax
      FROM   components_componentproperty
      WHERE  property_id IN (9102, 8801, 1234, 5678, 9876)  -- expand as needed
      GROUP  BY 1,2
      ) cp1
   GROUP  BY 1
   HAVING count(*) = 5  -- match IN expression
   ) cp2
JOIN   components_component c USING (id);
HAVING count(DISTINCT property_id) = 5