Gui*_*ido 5 sql postgresql grouping
我有一个 postgresql 表,其中包含仓库之间不同项目(模型)的移动。
例如,以下记录表示模型 1 的 5 件已从仓库 1 发送到仓库 2:
source target model units
------ ------ ----- -----
1 2 1 5
Run Code Online (Sandbox Code Playgroud)
我正在尝试构建一个 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
Run Code Online (Sandbox Code Playgroud)
结果应该是:
source target model diff
------ ------ ----- ----
1 2 1 2 -- 5 sent minus 3 received
1 2 2 1
Run Code Online (Sandbox Code Playgroud)
我想知道这是否可以通过单个 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);
Run Code Online (Sandbox Code Playgroud)
您可以使用两个子选择来完成此操作,这两个子选择将每个方向上的移动相加,然后将这两个子查询的结果合并并求和:
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
Run Code Online (Sandbox Code Playgroud)
这能满足您的需要吗?我没有可供测试的 Oracle 数据库,因此我希望分组表达式的规则与 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
Run Code Online (Sandbox Code Playgroud)