我想使用同一个id检索多行。因此,有了这个表“component_property”,我希望有2条记录作为结果,id:8和9,根据我的SQL查询(下面的检查),但当然,由于我正在检查是否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==>组件属性成分
id serial NOT NULL,
type_id integer NOT NULL,
name character varying(50) NOT NULL,
description character varying(255),
组件属性
id serial NOT NULL,
component_id integer NOT NULL,
property_id integer NOT NULL,
value character varying(255),
财产
id serial NOT NULL,
code character varying(10),
preferred_name character varying(50),
我的预期结果是:
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;
我们在这里汇集了一系列相关技术:
How to filter SQL results in a has-many-through relation
检查大量属性
您可以展开上面的查询,对于一手完整的属性,它将是最快的解决方案之一。对于更多的人来说,走这条路会更方便(也开始更快):
例如,对于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
的额外步骤只是必需的,因为显然(component_id, property_id)
中每个components_componentproperty
都有多个条目。我们可以把cp1
和cp2
合二为一HAVING count(DISTINCT property_id) = 5
但我希望这会更昂贵,因为
count(DISTINCT col)
需要每行一个排序操作。对于很长的列表
IN
是一个错误的选择。考虑:Optimizing a Postgres query with a large IN
关于sql - 使用AND和OR通过查询检索多行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29117449/