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

求助:PostgreSQL/SQLite3中表自连接实现同比(YoY)对比

实现单行展示同比(YoY)数据的SQL方案

没问题,我来帮你搞定这个同比单行展示的需求,不管用PostgreSQL还是SQLite都能轻松实现。核心思路是通过自连接关联当前日期和去年同期的数据,再把结果和其他表的查询结果合并。下面是具体方案:

核心逻辑说明

我们把sales表拆成两个逻辑实例:一个代表2017年1月7日的当前数据,另一个代表去年同一天(2016年1月7日)的同期数据。通过store和category保证维度匹配,再用日期偏移一年的规则关联两张"表",最终把去年的4个指标作为额外字段追加到当前数据的同一行。


1. PostgreSQL 实现代码

PostgreSQL支持直接用INTERVAL做日期运算,写法很简洁:

SELECT
  -- 当前周期(2017-01-07)的所有字段
  curr.we,
  curr.store,
  curr.category,
  curr.planu,
  curr.planrev,
  curr.merchu,
  curr.merchrev,
  -- 去年同期的指标,用ly_前缀做区分
  prev.planu AS ly_planu,
  prev.planrev AS ly_planrev,
  prev.merchu AS ly_merchu,
  prev.merchrev AS ly_merchrev
FROM sales curr
JOIN sales prev
  ON curr.store = prev.store
  AND curr.category = prev.category
  AND curr.we - INTERVAL '1 year' = prev.we
-- 筛选目标日期
WHERE curr.we = '2017-01-07'
-- 可选:按门店和品类排序,方便查看
ORDER BY curr.store, curr.category;

2. SQLite3 实现代码

SQLite需要用DATE()函数来计算去年同期日期,调整一下日期关联条件即可:

SELECT
  curr.we,
  curr.store,
  curr.category,
  curr.planu,
  curr.planrev,
  curr.merchu,
  curr.merchrev,
  prev.planu AS ly_planu,
  prev.planrev AS ly_planrev,
  prev.merchu AS ly_merchu,
  prev.merchrev AS ly_merchrev
FROM sales curr
JOIN sales prev
  ON curr.store = prev.store
  AND curr.category = prev.category
  AND DATE(curr.we, '-1 year') = prev.we
WHERE curr.we = '2017-01-07'
ORDER BY curr.store, curr.category;

与其他表结果的UNION整合

要把上述结果和其他合作伙伴的查询结果合并,只需要确保所有查询的列数、列顺序、数据类型完全一致,然后用UNION ALL(保留重复数据)或UNION(自动去重)拼接即可。示例如下:

-- 先执行sales表的同比查询
SELECT
  curr.we,
  curr.store,
  curr.category,
  curr.planu,
  curr.planrev,
  curr.merchu,
  curr.merchrev,
  prev.planu AS ly_planu,
  prev.planrev AS ly_planrev,
  prev.merchu AS ly_merchu,
  prev.merchrev AS ly_merchrev
FROM sales curr
JOIN sales prev
  ON curr.store = prev.store
  AND curr.category = prev.category
  AND curr.we - INTERVAL '1 year' = prev.we
WHERE curr.we = '2017-01-07'

-- 用UNION ALL连接其他表的同比查询(以partner_sales表为例)
UNION ALL

SELECT
  curr.we,
  curr.store,
  curr.category,
  curr.planu,
  curr.planrev,
  curr.merchu,
  curr.merchrev,
  prev.planu AS ly_planu,
  prev.planrev AS ly_planrev,
  prev.merchu AS ly_merchu,
  prev.merchrev AS ly_merchrev
FROM partner_sales curr
JOIN partner_sales prev
  ON curr.store = prev.store
  AND curr.category = prev.category
  AND curr.we - INTERVAL '1 year' = prev.we
WHERE curr.we = '2017-01-07'

ORDER BY store, category;

提示:如果是SQLite环境,把日期运算部分换成DATE(curr.we, '-1 year')就可以直接复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:06:41