SQL查询组并按字段值过滤

时间:2019-05-05 19:32:48

标签: sql postgresql

例如具有此表:

ID   ProdId   Status
1    111      None
2    111      Success
3    222      Process
4    222      Fail
5    333      Process
6    333      Process
7    444      None

我需要按字段ProdId进行分组,并排除所有包含Status的行-“成功”或“失败” 因此,此sql查询的结果必须为:

6    333      Process
7    444      None

有可能吗?

4 个答案:

答案 0 :(得分:1)

对于您发布的示例数据,下面的NOT EXISTS过滤将起作用:

select max(t.id) id, t.prodid, max(t.process)
from tablename t
where not exists (
  select 1 from tablename
  where prodid = t.prodid and status in ('Success', 'Fail')
)
group by t.prodid

尽管目前尚不清楚在有以下行的情况下需要什么:

5    333      Process
6    333      None

编辑:
发表评论后,我认为您需要此加入:

select t.* 
from tablename t inner join (
  select max(t.id) id, t.prodid
  from tablename t
  where not exists (
    select 1 from tablename
    where prodid = t.prodid and status in ('Success', 'Fail')
  ) 
  group by t.prodid
) g on g.id = t.id

请参见demo
结果:

| id  | prodid | status  |
| --- | ------ | ------- |
| 6   | 333    | Process |
| 7   | 444    | None    |

答案 1 :(得分:0)

我宁愿使用WITH子句作为聚合管道,然后过滤结果,因此您无需在子查询或WHERE语句中再次执行聚集。

WITH grouped AS 
(
    SELECT max(id) AS id, 
                prodid, array_agg(status) 
                AS statuses
    FROM tablename
    GROUP BY prodid
    )
SELECT * FROM grouped
WHERE    
    NOT('Fail' = ANY(statuses))
AND 
    NOT('Success' = ANY(statuses))

(请参阅:https://www.db-fiddle.com/f/okYf8wkyn7Aj8tKaGRWSft/0

现在,您并不是真的需要最大的ID或它的相应状态。我会发现检查产品在发展过程中具有哪些状态更为有用。

答案 2 :(得分:0)

使用窗口功能:

select id, prodid, status
from (select t.*,
             count(*) filter (where status in ('Success', 'Fail') as cnt
      from t
     ) t
where cnt = 0;

答案 3 :(得分:-1)

您可以在下面的查询中使用mySql数据库。如果您不希望使用count列,则可以从查询中删除“ count(*)”。

select * , count(*) from customers1 where status not in('success','fail') group by pordid;