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

MySQL技术问询:按日期分组展示部门促销销售及无销售日期

没问题,我来帮你搞定这个查询问题!

首先得理清你遇到的核心问题:

  • 当你把dp.product_id = pr.product_id加到WHERE子句时,左连接的特性直接失效了——这个条件会过滤掉所有pr.product_id为NULL的行,也就是没有销售的记录,自然就丢失了无销售的日期。
  • 另外你原来的查询会把每个促销活动(a/b/c)都单独显示一行,但你期望无销售的日期只保留一行NULL记录,而不是三行重复的空值。

解决方案:

我们需要先锁定目标campaign下的所有日期,再关联有实际销售的记录,最后对无销售的日期单独补充一行空值。这里用CTE(公共表表达式)来拆分逻辑,更清晰易懂:

WITH campaign_dates AS (
    -- 第一步:获取campaign_id=1对应的所有唯一日期
    SELECT DISTINCT DATE(created) AS created_date
    FROM promotion_result
    WHERE campaign_id = 1
),
valid_sales AS (
    -- 第二步:筛选出有实际销售的记录(排除product_id为NULL的行)
    SELECT 
        DATE(pr.created) AS created_date,
        pr.campaign_id,
        pr.promotion,
        pr.product_id
    FROM department dept
    JOIN department_campaign dc 
        ON dc.department_id = dept.id
    JOIN promotion_result pr 
        ON dc.campaign_id = pr.campaign_id
    WHERE dept.id = 2
      AND pr.campaign_id = 1
      AND pr.product_id IS NOT NULL
)
-- 第三步:合并有销售的记录和无销售日期的空值行
SELECT 
    created_date AS created,
    campaign_id AS campaign,
    promotion,
    product_id AS product
FROM valid_sales
UNION ALL
SELECT 
    created_date AS created,
    1 AS campaign,
    NULL AS promotion,
    NULL AS product
FROM campaign_dates cd
WHERE NOT EXISTS (
    -- 只补充那些没有销售记录的日期
    SELECT 1 FROM valid_sales vs WHERE vs.created_date = cd.created_date
)
ORDER BY created ASC, promotion ASC;

逻辑说明:

  1. campaign_dates:先把目标campaign下的所有日期提取出来,确保不会遗漏任何日期节点。
  2. valid_sales:只保留有实际销售的记录,避免左连接带来的多余空行。
  3. 最后合并查询:用UNION ALL把有销售的记录,和没有销售日期的单行空值记录合并,完美匹配你想要的结果。

为什么原来的查询不生效?

  • 你添加的dp.product_id = pr.product_id条件,把左连接变成了内连接——因为pr.product_id为NULL时,不可能和dp.product_id匹配,直接过滤掉了无销售的行。
  • 原来的GROUP BY会按每个促销活动分组,导致无销售日期出现三行空值,而我们需要的是将这些空值合并为一行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:52:53