使用SQL分组时计算行之间的差异

使用SQL分组时计算行之间的差异,sql,postgresql,grouping,Sql,Postgresql,Grouping,我有一个postgresql表,其中包含不同物料模型在仓库之间的移动 例如,以下记录表示模型1的5个单元已从仓库1发送至仓库2: source target model units ------ ------ ----- ----- 1 2 1 5 我正在尝试构建一个SQL查询,以获取发送和接收的单元之间的差异,并按模型分组。再举一个例子: source target model units ------ ------ ----- ----- 1

我有一个postgresql表,其中包含不同物料模型在仓库之间的移动

例如,以下记录表示模型1的5个单元已从仓库1发送至仓库2:

source target model units
------ ------ ----- -----
     1      2     1     5
我正在尝试构建一个SQL查询,以获取发送和接收的单元之间的差异,并按模型分组。再举一个例子:

source target model units
------ ------ ----- -----
     1      2     1     5  -- 5 sent from 1 to 2
     1      2     2     1
     2      1     1     2  -- 2 sent from 2 to 1
     2      1     1     1  -- 1 more sent from 2 to 1
结果应该是:

source target model diff
------ ------ ----- ----
     1      2     1    2   -- 5 sent minus 3 received
     1      2     2    1
我想知道这是否可以通过一个SQL查询实现

以下是表格创建脚本和一些数据,以防有人想尝试:

CREATE TEMP TABLE movements
(
    source  INTEGER,
    target  INTEGER,
    model   INTEGER,
    units   INTEGER
);

insert into movements values (1,2,1,5);
insert into movements values (1,2,2,1);
insert into movements values (2,1,1,2);
insert into movements values (2,1,1,1);

可以使用两个子选择来完成此操作,这两个子选择对每个方向上的移动进行求和,然后合并并求和这两个子查询的结果:

SELECT source, target, model, SUM(units)
FROM (
    SELECT source, target, model, SUM(units) AS units
    FROM movements
    WHERE source < target
    GROUP BY source, target, model
    UNION ALL
    SELECT target, source, model, SUM(-units) AS units
    FROM movements
    WHERE source > target
    GROUP BY source, target, model
) T1
GROUP BY source, target, model

这能满足你的需要吗?我没有Oracle DB可供测试,因此我希望分组表达式的规则与MS SQL Server相同

SELECT     
 CASE WHEN source < target THEN source ELSE target END AS source,
 CASE WHEN source < target THEN target ELSE source END AS target,
 SUM(CASE WHEN source < target THEN units ELSE -units END) AS Diff, 
    model
FROM  movements
GROUP BY
 CASE WHEN source < target THEN source ELSE target END,
 CASE WHEN source < target THEN target ELSE source END,
    model

谢谢,让我试试。您的查询与@Martin Smith提供的查询相比如何?该查询避免使用UNION ALL,而是使用一些CASE子句?@Guido:他的答案只扫描表一次,我的答案扫描表两次。你们有几排?性能是一个问题吗?我认为我的建议更清晰/易读,但这是我自己的观点,也是主观的。我对代码的格式做了一些修改,使其更加美观,但我必须同意5个重复的案例陈述会降低可读性。我认为我的答案可能更符合问题中单一SQL查询部分的精神,但由于只包含1个SELECT:-我将Martin的答案标记为有效,因为在他的查询中添加额外的过滤器更容易。这张桌子也相当大。谢谢你们两位。