【问题标题】:Reducing/summarising multiple tables with SQL?使用 SQL 减少/汇总多个表?
【发布时间】:2014-11-19 08:09:41
【问题描述】:

考虑两个表:

CREATE TABLE sales (
    saleid INT,
    saledateid INT,
    saleamount DECIMAL(12,2)
);

CREATE TABLE salelines (
    salelineid INT,
    saleid INT,
    quantity INT,
    unitamount DECIMAL(12,2)
);

如果我想计算每天的总销售额:

SELECT sum(quantity * unitamount)
FROM sales
JOIN salelines USING (saleid)
GROUP BY saledateid;

在大多数情况下,sales.saleamount 是该销售的销售线的总和。但在某些情况下,saleamount 会被调整,这就是我们单独存储它的原因。所以每天的实际总销售额为:

SELECT sum(saleamount)
FROM sales
GROUP BY saledateid;

但是,对于物化视图,我需要在同一个查询中同时使用这两种方法,以下方法不起作用,因为销售可能由多条销售线组成。

SELECT sum(quantity * unitamount), sum(saleamount)
FROM sales
JOIN salelines USING (saleid)
GROUP BY saledateid;

我该怎么做?我正在使用 PostgreSQL,但我更喜欢符合 SQL 的解决方案。

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    解决此问题的一种方法是向销售行添加序列号。然后你可以使用条件聚合只选择一个值:

    SELECT saledateid, sum(sl.quantity * sl.unitamount),
           sum(case when seqnum = 1 then s.saleamount end)
    FROM sales s JOIN
         (SELECT sl.*, row_number() over (partition by saleid order by saleid) as seqnum
          FROM salelines sl
         ) sl
         USING (saleid)
    GROUP BY saledateid;
    

    row_number() 是 ANSI 标准函数,可在大多数数据库中使用。您的问题最初以 MySQL 作为标签,但在那里不可用。

    【讨论】:

    • 为简洁起见,我没有提到salelines 有一个sequence INT,所以我可以使用sum(case when sequence = 1 then saleamount end)。谢谢!
    • @ElliotChance 。 . .这也适用于 MySQL。
    猜你喜欢
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多