You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中按日期分组计算col_a为空行占比的查询修正求助

PostgreSQL中按日期分组计算col_a为空行占比的查询修正求助

嗨,我来帮你搞定这个占比计算的问题!先理清楚你的需求:你需要把col_b按日期分组,统计每天里col_a为空的行占当天总行数的百分比,对吧?

先看看你提供的示例数据:

col_acol_b
A2025-04-28 16:23:55.961 -0400
2024-03-27 17:17:08.100 -0400
C2024-03-27 18:57:23.194 -0500
B2025-04-28 17:44:51.647 -0500
2023-04-28 10:47:30.667 -0400

你期望的结果是按日期分组,得到空值占比:

b_datepercentage
2023-04-2866
2024-03-2750

接下来说说你原来的查询哪里出问题了:

  • count(col_a=null) 这部分写法不对,因为col_a=null在PostgreSQL里会返回布尔值(true/false),而count()函数会把所有非空的布尔值都算入计数,不管是true还是false,这就导致你统计的空值数量完全错误。

给你修正后的查询,有两种写法都能实现需求:

方法一:使用FILTER子句(PostgreSQL 9.4+支持,语法更清晰)

SELECT
  col_b::date AS b_date,
  ROUND(
    (COUNT(*) FILTER (WHERE col_a IS NULL) * 100.0) / COUNT(*),
    0  -- 这里的0是保留0位小数,和你示例的整数结果对应,需要小数可调整
  ) AS percentage
FROM my_table
GROUP BY b_date
ORDER BY b_date ASC;

方法二:使用CASE表达式(兼容性更好)

SELECT
  col_b::date AS b_date,
  ROUND(
    (SUM(CASE WHEN col_a IS NULL THEN 1 ELSE 0 END) * 100.0) / COUNT(*),
    0
  ) AS percentage
FROM my_table
GROUP BY b_date
ORDER BY b_date ASC;

为什么这么改?

  1. 用COUNT(*) FILTER (WHERE col_a IS NULL) 或者SUM(CASE...)可以准确统计出当天col_a为空的行数
  2. 乘以100.0而不是100是为了避免整数除法(PostgreSQL里整数相除会直接取整,比如5/2会得到2而不是2.5)
  3. ROUND(..., 0)是为了把结果转成整数,和你示例里的66、50对应,如果需要保留小数可以调整这个参数

另外补充:如果只想保留有非零占比的日期,可以在GROUP BY后面加上HAVING COUNT(*) FILTER (WHERE col_a IS NULL) > 0,这样2025-04-28这种占比为0的日期就不会出现在结果里了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 09:49:33