按多个列和行查找条件sql查询
我在PostgreSQL中有路径和条件表。路径具有多个要选择的条件 带有(按多个列和行查找条件sql查询,sql,postgresql,relational-division,Sql,Postgresql,Relational Division,我在PostgreSQL中有路径和条件表。路径具有多个要选择的条件 带有(id,name)的路径表,带有(id,key,值,路径id)的条件表 我需要创建一个SQL查询,用于选择满足两个或多个条件输入(例如,30岁和男性性别)的单个路径。我已经尝试了任何,如下所示 SELECT p.*, array_agg(c.*) as criteria FROM paths as p INNER JOIN criteria as c ON c.path_id = p.id WHERE (c.key,
id
,name
)的路径表,带有(id
,key
,值
,路径id
)的条件表
我需要创建一个SQL查询,用于选择满足两个或多个条件输入(例如,30岁和男性性别)的单个路径。我已经尝试了任何
,如下所示
SELECT p.*, array_agg(c.*) as criteria
FROM paths as p
INNER JOIN criteria as c ON c.path_id = p.id
WHERE (c.key, c.value) = ANY (array[
("age","30"),
("gender","male")
])
GROUP BY p.id
但只要满足任何一个标准(无论年龄=30还是性别=“男性”并非两者都满足),就会得到一条路径。我用
ALL
替换了ANY
,但这根本不返回任何值。如果我正确地遵循了您的操作,您需要将条件移动到having
子句,而不是where
子句。此外,如果希望记录满足所有条件,则需要分别检查每个条件:
select p.*, array_agg(c.key || ':' || c.value) as criteria
from paths p
inner join criteria c on c.path_id = p.id
group by p.id
having
count(*) filter(where c.key = 'age' and c.value = '30') > 0
and count(*) filter(where c.key = 'gender' and c.value = 'male') > 0
这也可以用两个EXISTS
条件表示,这应该是一个有效的退出查询,索引位于条件(路径id、键、值)
(但随后您失去了聚合所有条件的能力):
在处理键/值对时,将标准聚合为JSON对象并使用Postgres的JSON函数选择所需的对象可能更容易:
select p.*, c.*
from paths as p
join (
select path_id, jsonb_object_agg(key, value) as all_criteria
from criteria
group by path_id
having jsonb_object_agg(key, value) @> '{"age": "30", "gender": "male"}'
) c on c.path_id = p.id
您必须添加
计数(c.id)=2
。因为您的条件数组有2个元素。将条件信息存储为path
表中的jsonb
列可能更容易。这有一个很好的属性,它可以确保结果中包含两个对,即使“age”或“gender”有多个值@GordonLinoff:通过将@>
更改为=
可以很容易地找到那些只有这些键/值对的键/值。在一个json中指定所有条件的能力对我来说是一个优势。谢谢非常感谢。第一个查询适用于我。我不知道你的答案和表演中没有名字的@a_horse_相比如何。我可能需要检查一下。
select p.*, c.*
from paths as p
join (
select path_id, jsonb_object_agg(key, value) as all_criteria
from criteria
group by path_id
having jsonb_object_agg(key, value) @> '{"age": "30", "gender": "male"}'
) c on c.path_id = p.id