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

如何在PostgreSQL中获取指定日期范围内的所有日期(含无销售日)

解决PostgreSQL查询包含无销售记录日期的问题

要实现包含指定日期范围内所有日期(即使无销售记录)的统计,核心思路是先生成完整的日期序列,再左连接原有销售数据,具体修改如下:

完整修改后的查询语句

WITH date_range AS (
    -- 生成2021-06-01至当前日期的所有日期
    SELECT generate_series(
        '2021-06-01'::date,
        current_date,
        '1 day'::interval
    ) AS sale_date
),
sales_data AS (
    -- 原有销售统计逻辑,封装为CTE
    SELECT 
        date(p.date_of_sale) AS sale_date,
        r.reservation_id AS "Reservation ID",
        pt.name AS "Product Type",
        scn.name AS "Sale Channel",
        CASE WHEN nullif(r.company_id,0) = 0 THEN 'B2C Customer' ELSE ca.name END AS "Company Account",
        ct.name AS "Class Type",
        op.name AS "Operator",
        p.description AS "Product Description",
        COUNT(p.id) AS "No of Car_Rentals"
    FROM products AS p
    JOIN reservations AS r ON p.reservation_id = r.id  
    LEFT JOIN companies AS ca ON ca.id = r.company_id
    LEFT JOIN class_types AS ct ON ct.id = ca.class_type_id
    JOIN product_types AS pt ON pt.id = p.product_type_id 
    JOIN sales_categories AS sc ON sc.id = p.sales_category_id
    JOIN sales_channels AS scn ON scn.id = r.sales_channel_id
    JOIN operators AS op ON op.id = p.operator_id 
    WHERE date(p.date_of_sale) >= '2021-06-01' 
      AND date(p.date_of_sale) <= current_date
      AND p.sales_category_id = 1
      AND p.status_id = 7 
      AND p.product_type_id = 6 
    GROUP BY date(p.date_of_sale), r.reservation_id, pt.name, scn.name, r.company_id, ca.name, ct.name, op.name, p.description
)
-- 左连接日期序列与销售数据,确保所有日期都被包含
SELECT 
    dr.sale_date AS "Date",
    sd."Reservation ID",
    sd."Product Type",
    sd."Sale Channel",
    sd."Company Account",
    sd."Class Type",
    sd."Operator",
    sd."Product Description",
    COALESCE(sd."No of Car_Rentals", 0) AS "No of Car_Rentals"
FROM date_range dr
LEFT JOIN sales_data sd ON dr.sale_date = sd.sale_date
ORDER BY dr.sale_date DESC;

关键修改说明

  1. 生成完整日期序列
    用PostgreSQL内置的generate_series函数创建目标范围内的所有日期,这是确保无销售日期被包含的核心。函数参数分别是起始日期、结束日期、间隔(这里是1天)。

  2. 封装原有统计逻辑
    将你原来的查询逻辑封装为sales_data公共表表达式(CTE),保留所有过滤、关联和分组规则,只提取有销售记录的数据。

  3. 左连接关联数据
    通过日期字段将date_range和sales_data做左连接,这样日期序列中的每个日期都会出现在结果中,没有对应销售数据的字段会显示NULL。

  4. 处理空值计数
    用COALESCE函数将无销售日期的No of Car_Rentals值从NULL替换为0,更符合统计场景的直观需求。

可选优化(按需调整)

如果希望无销售日期的其他字段(如"Reservation ID"、"Product Type")显示默认值而非NULL,可以给这些字段添加COALESCE处理,示例:

COALESCE(sd."Reservation ID"::text, 'N/A') AS "Reservation ID",
COALESCE(sd."Product Type", 'N/A') AS "Product Type"

注意:如果字段是数值类型,需要先转换为字符串再设置默认值,避免类型不匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:10:20