PostgreSQL查询返回过滤结果

时间:2020-11-08 22:18:56

标签: sql postgresql

我的查询

    select link.id, bti_status.bti_status from link
inner join bti
    on link.id = bti.id
inner join bti_status
    on bti.id = bti_status.bti_id

返回下表。

enter image description here

我希望该查询仅返回没有bti_status = 4的id的集合,因此在任何行中都不应该返回id = 403,因为第5行的bti_status值为4。 / p>

我尝试了以下查询,但不确定它是否可以正常工作。

    select link.id, bti_status.bti_status from link
inner join bti
    on link.id = bti.id
inner join bti_status
    on bti.id = bti_status.bti_id
where not exists (select bti_status from bti_status where bti_status = 4);

更新

关于@GMB答案,我的原始查询实际上与我发布的查询不同。原始查询为

select link.id, bti_status.bti_status, bti.id from link
inner join bti_link
    on link.id = bti_link.id
inner join bti
    on bti_link.bti_id = bti.id
inner join deadline
    on deadline.id = link.deadline_id
inner join bti_status
    on bti.id = bti_status.bti_id
where deadline.id = :id
and not exists (select bti_status from bti_status where bti_status = 4);

如果我尝试您的解决方案,我将无法正常工作

select l.id, bs.bti_status, b.id 
from (
        select l.id, bs.bti_status, b.id, 
            bool_or(bs.bti_status = 4) over(partition by l.id) has_status_4
        from link l
        inner join bti_link on l.id = bti_link.id
        inner join bti b on bti_link.bti_id = b.id
        inner join deadline d on d.id = l.deadline_id
        inner join bti_status bs on b.id = bs.bti_id
) t
where d.id = :id
and not has_status_4;

2 个答案:

答案 0 :(得分:1)

您可以使用窗口功能执行此操作。这是使用布尔窗口聚合的一种方法:

select id, bti_status
from (
    select l.id, bs.bti_status, 
        bool_or(bs.bti_status = 4) over(partition by l.id) has_status_4
    from link l
    inner join bti b on l.id = b.id
    inner join bti_status bs on b.id = bs.bti_id
) t
where not has_status_4

答案 1 :(得分:1)

正如GMB所说,窗口功能是一种方法。

您还可以使用CTE:

WITH data AS (
   SELECT link.id AS link_id, bti_status.bti_status, bti.id AS bti_id
   FROM link
   INNER JOIN bti_link ON link.id = bti_link.id
   INNER JOIN bti ON bti_link.bti_id = bti.id
   INNER JOIN deadline ON deadline.id = link.deadline_id
   INNER JOIN bti_status ON bti.id = bti_status.bti_id
   WHERE deadline.id = :id
   )
SELECT * 
FROM data
WHERE link_id NOT IN (
   SELECT link_id 
   FROM data 
   WHERE bti_status = 4)
相关问题