You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PostgreSQL:连接查询获取行数及按用户审计数排序统计

解决按审计记录数量排序的用户统计问题

咱们先捋清楚你原查询的问题:你现在的语句是把学校、用户和每条审计记录做了关联,所以返回的是每条审计记录对应的用户信息,而不是每个用户的审计记录总数,而且排序逻辑也不是你要的按审计数量排序,而是按用户创建时间倒序,这完全不符合你的需求~

下面给你两种场景的正确查询方案:

场景1:只统计有审计记录的用户

如果只需要展示那些有过操作审计的用户,用这个查询,核心是通过GROUP BY按用户维度分组,再用COUNT统计每个用户的审计记录数,最后按统计数倒序:

SELECT 
    s.user_created,
    u.first_name,
    u.last_name,
    u.email,
    COUNT(a.audit_id) AS audit_count  -- 用审计表主键统计,避免统计NULL行
FROM 
    cbrain_school s
INNER JOIN 
    ugrp_user u ON s.user_created = u.user_id
INNER JOIN 
    audit a ON u.user_id = a.user_id
GROUP BY 
    s.user_created, u.first_name, u.last_name, u.email
ORDER BY 
    audit_count DESC;

场景2:包含没有审计记录的用户(审计数显示为0)

如果想把那些从未产生过审计记录的用户也列出来(审计数显示0),只需要把和audit表的关联改成LEFT JOIN就行,这样没有审计记录的用户也会被保留,统计数自然就是0:

SELECT 
    s.user_created,
    u.first_name,
    u.last_name,
    u.email,
    COUNT(a.audit_id) AS audit_count
FROM 
    cbrain_school s
INNER JOIN 
    ugrp_user u ON s.user_created = u.user_id
LEFT JOIN 
    audit a ON u.user_id = a.user_id
GROUP BY 
    s.user_created, u.first_name, u.last_name, u.email
ORDER BY 
    audit_count DESC;

额外小提示

  • 分组字段要注意:严格SQL模式下,GROUP BY必须包含所有SELECT里没被聚合的字段,所以这里把用户的几个标识字段都加进去了
  • 如果需要在审计数相同的情况下,再按用户创建时间排序,可以把ORDER BY改成audit_count DESC, u.created_time DESC
  • COUNT(a.audit_id)COUNT(*)更准确,因为LEFT JOIN后无审计记录的行里,a表的字段都是NULL,COUNT会忽略这些NULL值,刚好得到0的统计结果

内容的提问来源于stack exchange,提问作者Geo Thomas

火山引擎 最新活动