代码之家  ›  专栏  ›  技术社区  ›  vektor

从每个组中选择一行匹配或是回退

  •  1
  • vektor  · 技术社区  · 6 年前

    使用PostgreSQL 9.6,如何从这样的数据中获取我:

    group | foo | value
    ------+-----+------
    1     | A   | a
    1     | B   | b
    1     | C   | c
    2     | B   | b2
    2     | A   | a2
    3     | B   | b3
    3     | C   | c3
    

    每行一个 group 以便:

    • 如果有与 foo = A 拿着它,
    • 否则,从该组中抽取任何行?

    示例输出:

    group | foo | value
    ------+-----+------
    1     | A   | a
    2     | A   | a2
    3     | B   | b3 <- chosen one row from group 3
    
    3 回复  |  直到 6 年前
        1
  •  3
  •   Vao Tsun    6 年前
    t=# select distinct on ("group") "group", foo, value 
    from table
    order by "group", foo = 'A' DESC;
     group  |  foo  | value
    --------+-------+-------
     1      |  A    |  a
     2      |  B    |  b2
     3      |  B    |  b3
    (3 rows)
    

    我想 neatest 会是 DISTINCT ON

        2
  •  1
  •   Giorgos Betsos    6 年前

    试试这个:

    SELECT "group", "foo", "value"
    FROM (
    SELECT "group", "foo", "value",
           ROW_NUMBER() OVER (PARTITION BY "group" 
                              ORDER BY CASE 
                                          WHEN "foo" = 'A' THEN 1
                                          ELSE 2
                                       END, "foo") AS seq
    FROM Table1) AS t
    WHERE t.seq = 1
    

    查询使用 ROW_NUMBER 有条件的 ORDER BY 条款,以便优先考虑 'A' 其他记录的记录。

    Demo here

        3
  •  0
  •   vektor    6 年前

    以下似乎对我有用:

    SELECT DISTINCT
      group,
      first_value(foo) OVER (PARTITION BY group ORDER BY foo = 'A' DESC) 'foo',
      first_value(value) OVER (PARTITION BY group ORDER BY foo = 'A' DESC) 'value'
    FROM ...
    

    如果需要指定选取回退行的条件,可以通过扩展 ORDER BY 条款,例如 ORDER BY foo = 'A' DESC, foo ASC .