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

如何合并两个SQL查询:门店日销售额与月销售占比计算

没问题,这个需求完全可以实现!其实你不用纠结子查询嵌套的复杂写法,用SQL的窗口函数就能一步搞定,逻辑还更清晰。

最优解决方案:用窗口函数合并查询

首先假设你的销售表结构大概是这样的(如果和实际不符,直接对应调整字段名即可):

CREATE TABLE sales (
    store_id INT,
    sale_date DATE,
    amount DECIMAL(10,2)
);

我们可以直接在一个查询里同时算出每日销售额、对应门店的月度总销售额,以及占比,不需要拆成两个查询:

SELECT
    store_id,
    sale_date,
    SUM(amount) AS daily_sales,
    -- 计算当前门店当月的总销售额,窗口函数限定范围为「同一门店+同一月份」
    SUM(SUM(amount)) OVER (PARTITION BY store_id, DATE_TRUNC('month', sale_date)) AS monthly_total_sales,
    -- 计算占比,用NULLIF避免当月无销售额时出现除以0的错误
    ROUND(
        SUM(amount) / NULLIF(SUM(SUM(amount)) OVER (PARTITION BY store_id, DATE_TRUNC('month', sale_date)), 0) * 100,
        2
    ) AS daily_sales_percentage
FROM sales
-- 筛选去年指定月份的数据,比如去年10月(可根据实际需求修改日期范围)
WHERE
    sale_date >= DATE_TRUNC('year', CURRENT_DATE) - INTERVAL '1 year' + INTERVAL '9 months'
    AND sale_date < DATE_TRUNC('year', CURRENT_DATE) - INTERVAL '1 year' + INTERVAL '10 months'
GROUP BY store_id, sale_date
ORDER BY store_id, sale_date;

关键逻辑拆解

  • 窗口函数SUM(...) OVER (...):这里用了嵌套聚合——先按门店+日期分组算出每日销售额,再用窗口函数对「同一门店+同一月份」的所有数据求和,得到月度总销售额,全程只需要扫描一次表。
  • DATE_TRUNC('month', sale_date):把日期截断到月份维度,确保同一门店同一月份的所有数据被分到同一个计算窗口里。
  • NULLIF:如果某个门店当月没有销售额,NULLIF会把除数转为NULL,避免触发除以0的报错,此时占比会显示为NULL,你也可以根据需求改成0。

为什么你之前的子查询方法出问题?

你提到把第一个查询嵌入第二个查询的FROM部分却选不到列,大概率是因为子查询没有起别名,或者关联逻辑没写对。如果一定要用子查询的方式(不推荐,效率低于窗口函数),可以这么写:

SELECT
    d.store_id,
    d.sale_date,
    d.daily_sales,
    m.monthly_total_sales,
    ROUND(d.daily_sales / NULLIF(m.monthly_total_sales, 0) * 100, 2) AS daily_sales_percentage
FROM (
    -- 子查询1:获取每日销售额
    SELECT store_id, sale_date, SUM(amount) AS daily_sales
    FROM sales
    WHERE sale_date BETWEEN '2023-10-01' AND '2023-10-31'
    GROUP BY store_id, sale_date
) d
JOIN (
    -- 子查询2:获取各门店月度总销售额
    SELECT store_id, DATE_TRUNC('month', sale_date) AS sale_month, SUM(amount) AS monthly_total_sales
    FROM sales
    WHERE sale_date BETWEEN '2023-10-01' AND '2023-10-31'
    GROUP BY store_id, DATE_TRUNC('month', sale_date)
) m ON d.store_id = m.store_id AND DATE_TRUNC('month', d.sale_date) = m.sale_month
ORDER BY d.store_id, d.sale_date;

不过这种写法需要两次扫描销售表,性能不如窗口函数方案,所以优先推荐第一种写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:30:30