【问题标题】:Select rows where partition meets condition (PostgreSQL)选择分区满足条件的行(PostgreSQL)
【发布时间】:2020-04-12 05:10:24
【问题描述】:

我找不到具有这些特征的类似问题,如果重复,我将关闭该问题。

假设我在 PostgreSQL 数据库中有下表:

  | serverdate | colA | colB | colC | colD
  |-------------------------------------------
0 | 2019-12-01 |    a | OK   | 10   | string1
1 | 2019-12-02 |    a | OK   | 10   | string2
2 | 2019-12-02 |    a | NOK  | 100  | string3
3 | 2019-12-01 |    b | OK   | 0    | string1
4 | 2019-12-03 |    b | OK   | 1    | string1
5 | 2019-12-05 |    c | NOK  | 0    | string2
5 | 2019-12-07 |    d | OK   | 10   | string3
5 | 2019-12-08 |    d | EX   | 1000 | string4
5 | 2019-12-12 |    e | OK   | 1    | string5

我想选择适用以下条件的所有行(我不知道如何准确地表达这个条件,一个例子更清楚):

对于 colA 中的所有组,检查 colB 中是否存在 NOK。如果分组中有任何 NOK,则不要选择该组的任何行

例如,对于提到的表,结果将是:

  | serverdate | colA | colB | colC | colD
  |-------------------------------------------
3 | 2019-12-01 |    b | OK   | 0    | string1
4 | 2019-12-03 |    b | OK   | 1    | string1
5 | 2019-12-07 |    d | OK   | 10   | string3
5 | 2019-12-08 |    d | EX   | 1000 | string4
5 | 2019-12-12 |    e | OK   | 1    | string5

关于如何进行此查询的任何想法?建议使用简单。

提前致谢!

【问题讨论】:

    标签: sql postgresql grouping


    【解决方案1】:

    NOT EXISTS 是一个规范的解决方案:

    select t.*
    from t
    where not exists (select 1
                      from t t2
                      where t2.cola = t.cola and t2.colb = 'NOK'
                     );
    

    【讨论】:

    • 当我尝试这个解决方案时,它起作用了,但是如果我在表中不存在的条件中输入一个值(例如,而不是 t2.colb = 'NOK',使用 t2.colb = 'AK'),结果是一个空表。
    • @jcf 。 . .如果您输入的值不在表中,它应该返回所有行。
    【解决方案2】:

    也许窗口函数可以提供帮助:

    SELECT cola, colb, ...
    FROM (SELECT cola, colb, ...,
                 bool_or(colb = 'NOK')
                    OVER (PARTITION BY cola) AS hasnok
          FROM tab) AS q
    WHERE NOT hasnok;
    

    【讨论】:

      猜你喜欢
      • 2019-04-24
      • 1970-01-01
      • 2011-07-20
      • 2017-11-15
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2017-10-22
      相关资源
      最近更新 更多