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

PostgreSQL统计上周按天分组销售数据 无销售日补0失效问题

PostgreSQL按星期统计上周销售数据补全0值方案

问题根因

coalesce函数仅能对结果集中已存在行的空值做替换,无法生成原本不存在的记录行。直接从销售关联表做分组聚合的写法,会导致没有销售记录的星期不会出现在分组结果中,自然无法通过coalesce补0。

修复逻辑

先构造上周完整7天的基准日期序列,再通过左连接关联按天聚合的销售统计结果,未匹配到销售数据的日期会返回空值,此时用coalesce即可正常补0。

修正后SQL代码

WITH last_week_days AS (
    SELECT
        day_series AS order_date,
        to_char(day_series, 'Dy') AS day
    FROM generate_series(
        date_trunc('week', CURRENT_DATE) - INTERVAL '7 days',
        date_trunc('week', CURRENT_DATE) - INTERVAL '1 day',
        INTERVAL '1 day'
    ) AS day_series
),
daily_sales AS (
    SELECT
        DATE(s.order_time) AS stat_date,
        COUNT(o.menu_item_id) AS qty_sold,
        SUM(m.price - m.cost) AS total_profit
    FROM sales_order s
    INNER JOIN order_item o ON o.sales_order_id = s.id
    INNER JOIN menu_item m ON m.id = o.menu_item_id
    WHERE s.order_time >= date_trunc('week', CURRENT_DATE) - INTERVAL '7 days'
      AND s.order_time < date_trunc('week', CURRENT_DATE)
    GROUP BY DATE(s.order_time)
)
SELECT
    lwd.day,
    COALESCE(ds.qty_sold, 0) AS qty_sold,
    COALESCE(ds.total_profit, 0) AS total_profit
FROM last_week_days lwd
LEFT JOIN daily_sales ds ON lwd.order_date = ds.stat_date
ORDER BY lwd.order_date ASC;

注意事项

  • 原SQL的时间过滤条件date_trunc('week', now())::date - 5范围不准确,会遗漏上周的部分日期,修正后用明确的上周一至上周日的闭开区间,不会漏算或多算数据
  • 不要直接按星期缩写字符串排序:不同语言环境下星期缩写的字符串排序规则和实际周顺序不一致,按基准日期排序可以保证结果始终按周一到周日的顺序返回
  • 必须使用基准日期表左连接销售统计结果,才能保留完整7天的所有行,这是coalesce能正常补0的前提

内容的提问来源于stack exchange,提问作者Ummulkhair Kadri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 15:30:05