SQL 查询 where has children with conditions
SQL query where has children with conditions
假设我有:
- a parents table 包含以下列:(id, name)
- a children attributes table 包含以下列:(id, child_id, parent_id, 属性, attribute_value)
现在我想过滤掉任何 parent id 的 ,它至少有一个 child 并且:
- 属性 =>
intelligence
共 5
- 属性 =>
health
共 4
其中一个 child 的 intelligence
为 5,health
为 4,或者一个 child 的 intelligence
为 5,另一个 child 有 health
的 4.
如何在 PostgreSQL 中查询? 谢谢
如果您只想要 parents 信息:
SELECT
DISTINCT parents.id, parents.name
FROM
parents
LEFT JOIN attributes ON parents.id = attributes.parent_id
WHERE
(attribute = 'intelligence' AND attribute_value = 5)
OR (attribute = 'health' AND attribute_value = 4)
首先我们需要加入表 -- 像这样
select p.id as p_id, p.name as parent_name,
k.* -- we won't need this in later versions
from parent p
join kidatt k on p.id = k.parent_id
现在我们有两个我们关心的属性——让我们进行一个查询来显示那些
select p.id as p_id, p.name as parent_name,
case when k.attribute = 'intelligence' and k.attribute_value = 5 then 1 else 0 end as has_a1,
case when k.attribute = 'health' and k.attribute_value = 4 then 1 else 0 end as has_a2
from parent p
join kidatt k on p.id = k.parent_id
我们现在有一个查询,其中每行都有一个 1
现在我们按 parent.
分组
select p.id as p_id, p.name as parent_name,
SUM(case when k.attribute = 'intelligence' and k.attribute_value = 5 then 1 else 0 end) as has_a1,
SUM(case when k.attribute = 'health' and k.attribute_value = 4 then 1 else 0 end) as has_a2
from parent p
join kidatt k on p.id = k.parent_id
group by p.id, p.name
现在我们有一个查询,如果一个或多个 child 有 a1 和 a2 大于 0。
现在select结果
select *
from (
select p.id as p_id, p.name as parent_name,
SUM(case when k.attribute = 'intelligence' and k.attribute_value = 5 then 1 else 0 end) as has_a1,
SUM(case when k.attribute = 'health' and k.attribute_value = 4 then 1 else 0 end) as has_a2
from parent p
join kidatt k on p.id = k.parent_id
group by p.id, p.name
)
where has_a1 > 0 and has_a2 > 0
注意——我写这个查询并不是为了最好的解决这个问题的方法——相反,我写它的方式是向您展示如何在 SQL 中“思考”并通过一系列步骤解决问题。
我必须进行测试才能确定,但我希望这是执行此查询的最快方法(取决于数据和索引等)
select distinct p.id as p_id, p.name as parent_name,
from parent p
join kidatt k on p.id = k.parent_id
where k.attribute = 'intelligence' and k.attribute_value = 5
intersect
select distinct p.id as p_id, p.name as parent_name,
from parent p
join kidatt k on p.id = k.parent_id
where k.attribute = 'health' and k.attribute_value = 4
你可以做
的交集
- parents children 智力 5
- parents children 生命值 4
(SELECT parent_id
FROM tab
WHERE attribute = 'intelligence'
AND attribute_value = 5 )
INTERSECT
(SELECT parent_id
FROM tab
WHERE attribute = 'health'
AND attribute_value = 4 )
假设我有:
- a parents table 包含以下列:(id, name)
- a children attributes table 包含以下列:(id, child_id, parent_id, 属性, attribute_value)
现在我想过滤掉任何 parent id 的 ,它至少有一个 child 并且:
- 属性 =>
intelligence
共 5 - 属性 =>
health
共 4
其中一个 child 的 intelligence
为 5,health
为 4,或者一个 child 的 intelligence
为 5,另一个 child 有 health
的 4.
如何在 PostgreSQL 中查询? 谢谢
如果您只想要 parents 信息:
SELECT
DISTINCT parents.id, parents.name
FROM
parents
LEFT JOIN attributes ON parents.id = attributes.parent_id
WHERE
(attribute = 'intelligence' AND attribute_value = 5)
OR (attribute = 'health' AND attribute_value = 4)
首先我们需要加入表 -- 像这样
select p.id as p_id, p.name as parent_name,
k.* -- we won't need this in later versions
from parent p
join kidatt k on p.id = k.parent_id
现在我们有两个我们关心的属性——让我们进行一个查询来显示那些
select p.id as p_id, p.name as parent_name,
case when k.attribute = 'intelligence' and k.attribute_value = 5 then 1 else 0 end as has_a1,
case when k.attribute = 'health' and k.attribute_value = 4 then 1 else 0 end as has_a2
from parent p
join kidatt k on p.id = k.parent_id
我们现在有一个查询,其中每行都有一个 1
现在我们按 parent.
分组select p.id as p_id, p.name as parent_name,
SUM(case when k.attribute = 'intelligence' and k.attribute_value = 5 then 1 else 0 end) as has_a1,
SUM(case when k.attribute = 'health' and k.attribute_value = 4 then 1 else 0 end) as has_a2
from parent p
join kidatt k on p.id = k.parent_id
group by p.id, p.name
现在我们有一个查询,如果一个或多个 child 有 a1 和 a2 大于 0。
现在select结果
select *
from (
select p.id as p_id, p.name as parent_name,
SUM(case when k.attribute = 'intelligence' and k.attribute_value = 5 then 1 else 0 end) as has_a1,
SUM(case when k.attribute = 'health' and k.attribute_value = 4 then 1 else 0 end) as has_a2
from parent p
join kidatt k on p.id = k.parent_id
group by p.id, p.name
)
where has_a1 > 0 and has_a2 > 0
注意——我写这个查询并不是为了最好的解决这个问题的方法——相反,我写它的方式是向您展示如何在 SQL 中“思考”并通过一系列步骤解决问题。
我必须进行测试才能确定,但我希望这是执行此查询的最快方法(取决于数据和索引等)
select distinct p.id as p_id, p.name as parent_name,
from parent p
join kidatt k on p.id = k.parent_id
where k.attribute = 'intelligence' and k.attribute_value = 5
intersect
select distinct p.id as p_id, p.name as parent_name,
from parent p
join kidatt k on p.id = k.parent_id
where k.attribute = 'health' and k.attribute_value = 4
你可以做
的交集- parents children 智力 5
- parents children 生命值 4
(SELECT parent_id
FROM tab
WHERE attribute = 'intelligence'
AND attribute_value = 5 )
INTERSECT
(SELECT parent_id
FROM tab
WHERE attribute = 'health'
AND attribute_value = 4 )