代码之家  ›  专栏  ›  技术社区  ›  Hommer Smith

PostgreSQL计数,条件基于列

  •  1
  • Hommer Smith  · 技术社区  · 6 年前

    我有张桌子叫 admin_descriptions 包含以下列:

    description_id , value , admin_id , valid_at

    还有桌子 admins 其中包含以下列:

    state

    我想要一个查询 描述ID 它给出了使用该描述的活动管理员的计数。考虑管理员的描述 习惯于 只要里面有一排 管理描述 描述ID A NOT NULL value 以及 验证程序 比任何其他具有 NULL value 为此 描述ID .

    因此,示例数据:

    Row 1:
    description_id: 1
    value: 'foo'
    admin_id: 2
    valid_at: '2010-01-10'
    
    Row 2:
    description_id: 1
    value: NULL
    admin_id: 2
    valid_at: '2012-01-10'
    
    Row 2:
    description_id: 1
    value: 'some value'
    admin_id: 4
    valid_at: '2014-01-10'
    

    查询时的计数 description_id = 1 是1。只考虑第三排。因为即使有第一行的值不为空,也有第2行对同一管理员id及其 价值 是空的。

    我可以不考虑 验证程序 通过:

    SELECT COUNT(DISTINCT(ad.id)) AS COUNT
    FROM admin_descriptions ad
    JOIN admins ON admins.id = ad.admin_id
    WHERE ad.description_id = 1
    AND admins.state = 'active'
    

    如何修改此查询以考虑到 验证程序 对于每个管理员ID/描述ID组合?

    2 回复  |  直到 6 年前
        1
  •  0
  •   Gordon Linoff    6 年前

    我会用 distinct on 要获取最新的管理说明,然后从中进行聚合:

    select count(*) as num_valid_admins
    from (select distinct on (ad.admin_id) ad.*
         from admin_descriptions ad
         where ad.description_id = XXX
         order by ad.admin_id, ad.valid_at desc
        ) ad
    where ad.value is not null;
    
        2
  •  0
  •   Dan    6 年前

    我认为这样可以让您检查每个分组id的有效值。

    SELECT
      COUNT(ad.id)
    FROM admin_description ad
      INNER JOIN admins ON admins.id = ad.admin_id
        AND admins.state = 'active'
    WHERE
      1 = 1
      -- AND valid_at -- However you want to handle valid_at
    GROUP BY ad.id;
    

    假设每个管理员id/描述id组合总是唯一的。

    如果没有,也许你可以尝试分组 id, admin_id, description_id 先过滤掉重复的。