使用 AND 和 OR 通过查询检索多行
Retrieve multiple rows with query using AND and OR
我想使用相同的 ID 检索多行。因此有了这个 table "component_property",我想根据我的 SQL 查询(检查下面)得到 2 条记录,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_property <=== 属性
组件
id serial NOT NULL,
type_id integer NOT NULL,
name character varying(50) NOT NULL,
description character varying(255),
component_property
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
的额外步骤只是必要的,因为您显然在 components_componentproperty
中每个 (component_id, property_id)
有多个条目。我们可以将cp1
和cp2
合二为一并检查
HAVING count(DISTINCT property_id) = 5
但我预计这会更昂贵,因为 count(DISTINCT col)
每行需要一次排序操作 。
对于非常长的列表,IN
是一个糟糕的选择。考虑:
我想使用相同的 ID 检索多行。因此有了这个 table "component_property",我想根据我的 SQL 查询(检查下面)得到 2 条记录,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_property <=== 属性
组件
id serial NOT NULL,
type_id integer NOT NULL,
name character varying(50) NOT NULL,
description character varying(255),
component_property
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
的额外步骤只是必要的,因为您显然在 components_componentproperty
中每个 (component_id, property_id)
有多个条目。我们可以将cp1
和cp2
合二为一并检查
HAVING count(DISTINCT property_id) = 5
但我预计这会更昂贵,因为 count(DISTINCT col)
每行需要一次排序操作 。
对于非常长的列表,IN
是一个糟糕的选择。考虑: