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

发布于 2024-08-31 18:59:11 字数 1058 浏览 5 评论 0原文

我有一个 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);

I have a postgresql table containing movements of different items (models) between warehouses.

For example, the following record means that 5 units of model 1 have been sent form warehouse 1 to 2:

source target model units
------ ------ ----- -----
     1      2     1     5

I am trying to build a SQL query to obtain the difference between units sent and received, grouped by models. Again with an example:

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

The result should be:

source target model diff
------ ------ ----- ----
     1      2     1    2   -- 5 sent minus 3 received
     1      2     2    1

I wonder if this is possible with a single SQL query.

Here is the table creation script and some data, just in case anyone wants to try it:

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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无敌元气妹 2024-09-07 18:59:11

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

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

You can do this with two subselects which sum the movements in each direction, and then union and sum the results of those two subqueries:

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
傲鸠 2024-09-07 18:59:11

这能满足您的需要吗?我没有可供测试的 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

Does this do what you need? I don't have an Oracle DB to test against so I hope the rules on Grouping expressions are the same as for 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文