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

自连接表获取去年数据时如何处理缺失日期问题

解决FULL JOIN导致的重复行及缺失日期问题

我来帮你搞定这个问题!你的需求很明确:要为每行数据匹配去年同期同渠道的会话数,同时还要保留那些只有今年数据或只有去年数据的日期-渠道组合,但原始的FULL JOIN语句不仅没达到预期,还出现了行重复和格式混乱的问题。

问题根源分析

原始的FULL JOIN虽然理论上会保留左右表中不匹配的行,但它没有先确保所有需要的日期-渠道组合都被覆盖。当某条记录在另一边没有匹配项时,会生成结构异常的行(比如你的实际输出里出现了孤立的数值),同时还会漏掉那些需要展示的“空数据”行(比如2018年2月2日的Organic渠道)。

正确解决方案

我们需要先构建出所有可能的日期-渠道组合,再分别左连接今年和去年的数据,这样就能保证每个组合都有一行,且数据对应正确。

修正后的SQL语句

WITH all_dates_channels AS (
  -- 生成所有日期和渠道的笛卡尔积,确保每个日期-渠道组合都被包含
  SELECT DISTINCT tj.Date FROM testjoin tj
  CROSS JOIN
  SELECT DISTINCT tj.Channel FROM testjoin tj
)
SELECT
  adc.Date,
  adc.Channel,
  ty.Sessions AS Sessions,
  ly.Sessions AS Sessions_LY
FROM all_dates_channels adc
-- 左连接获取当前日期-渠道的会话数(无数据则为NULL)
LEFT JOIN testjoin ty
  ON ty.Date = adc.Date AND ty.Channel = adc.Channel
-- 左连接获取去年同期同渠道的会话数(无数据则为NULL)
LEFT JOIN testjoin ly
  ON ly.Date = DATE_SUB(adc.Date, INTERVAL 1 YEAR) 
  AND ly.Channel = adc.Channel
-- 按渠道和日期排序,让结果更清晰
ORDER BY adc.Channel, adc.Date;

代码解释

  1. CTE all_dates_channels:通过交叉连接(CROSS JOIN)原始表中所有唯一的日期和渠道,生成所有可能的日期-渠道组合。这一步是关键,确保不会漏掉任何需要展示的组合。
  2. 第一个左连接:关联原始表,获取当前日期-渠道的会话数,如果该组合没有数据,Sessions字段会显示NULL。
  3. 第二个左连接:关联原始表中日期减一年且渠道相同的记录,获取去年的会话数,无匹配则显示NULL。
  4. 排序:最终结果按渠道和日期排序,和你期望的输出格式完全一致。

验证结果

运行这段SQL后,你会得到完全符合期望的输出:

Date        Channel  Sessions  Sessions_LY
01/01/2017  Email    5         null
02/02/2017  Email    10        null
01/01/2018  Email    11        5
02/02/2018  Email    17        10
01/01/2017  Organic  10        null
02/02/2017  Organic  15        null
01/01/2018  Organic  20        10
02/02/2018  Organic  null      15

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:05:35