根据条件对列求和

3

我正在处理一个 SQL 查询语句。查询大概如下:

Select 
    a.field1,
    b.field2,
    c.field3,
    c.field4,
    b.filed5,
    a.field6,
    d.field7 
from 
    a 
    Inner join b on a.field1 = b.field1 
    right join c on b.field2 = c.field3 
    left  join d on d.filed3 = a.field1 
where some conditions;

上述代码的输出结果可能类似于下面这样:
field1 | field2 | field3 | field4 | field5 | field6 | field7
--------------------------------------------------------------
name   | value1 | other1 | 1      | diff   |   new  | 100
name1  | value2 | other2 | 1      | diff1  |   new1 | 100
name2  | value3 | other3 | 2      | diff2  |   new2 | 100

所以我需要在结果中添加一个新列,它根据field4的值(如果它们相同)来总结field7

在SQL中是否可以做到这一点?我尝试在这里使用Group by field 4,但是我得到一个错误,说field1应该被用于group by。因此,我无法如预期的那样获得结果。

期望结果:

field1 | field2 | field3 | field4 | field5 | field6 | field7
--------------------------------------------------------------
name   | value1 | other1 | 1      | diff   |   new  | 200
some   | value3 | other3 | 2      | diff2  |   new2 | 100

基本上,我想根据条件删除一列并对最后一个字段求和。

任何建议都有帮助。


1
你能展示一下应该对应你的示例数据的结果吗? - GMB
@GMB 完成。所以基本上我想在上述最后一个字段求和后,根据字段1删除列。 - ging
1
谢谢!另一个问题:在结果集中,field1field6的值是否都相等?如果不是,您想保留哪个记录作为分组? - GMB
你可能想用更有意义的数据替换样本数据中的'some' - GMB
1
感谢您的努力。在我看来,您的问题现在看起来很好! - GMB
显示剩余3条评论
2个回答

2
为了计算在具有相同field4的记录组中field7的总和,您可以使用窗口函数SUM(...) OVER(...)
为了仅保留具有相同field4的记录组中的一个记录,您可以在内部查询中使用ROW_NUMBER(),并在外部查询中过滤掉不需要的记录。请注意,您需要一个排序标准来可靠地选择每个组中应保留哪个记录。我选择使用field1(根据需要更改):
您的(伪)查询应如下所示:
SELECT * FROM (
    SELECT 
        a.field1,
        b.field2,
        c.field3,
        c.field4,
        b.filed5,
        a.field6,
        SUM(d.field7) OVER(PARTITION BY c.field4) sm,
        ROW_NUMBER()  OVER(PARTITION BY c.field4 ORDER BY a.field1) rn,
    FROM
        a 
        INNER JOIN b on a.field1 = b.field1 
        RIGHT JOIN c on b.field2 = c.field3 
        LEFT  JOIN d on d.field3 = a.field1 
    WHERE some conditions
) x
WHERE rn = 1

提示:您可以独立运行内部查询以查看其返回的结果(这有助于理解逻辑)。
最初的回答:提示:您可以独立运行内部查询以查看其返回的结果(这有助于理解逻辑)。

看起来 Over Partition 给出了错误的总和。对于 field7,我得到的不是 200、100,而是 300、200。 - ging
行号()没有起作用,但是Over Partition 起了作用。谢谢。我已经开了一个不同的线程来更好地理解另一个问题。 - ging

0

您可以使用按查询分区来根据字段4创建单独的分区,然后进行求和

SELECT
z.* FROM (SELECT
a.field1,
b.field2,
c.field3,
b.filed5,
a.field6,
SUM(d.field4) OVER (PARTITION BY a.field1, b.field2, c.field3, b.filed5, a.field6) AS field7,
ROW_NUMBER() OVER (PARTITION BY c.field4 ORDER BY c.field4) AS rank FROM a INNER JOIN b
ON a.field1 = b.field1 RIGHT JOIN c
ON b.field2 = c.field3 LEFT JOIN d
ON d.filed3 = a.field1 where some conditions; ) z WHERE z.rank = 1

1
好的,基本上是相同的答案,将总和列别名重命名为field7。我已经更新了答案。 - AmilaMGunawardana
这也会删除第二个不需要的列吗? - ging
看起来你的查询正在将field7上的所有值加起来,即使field4不同。 - ging
嗨@Amila,你的第一个答案有点起作用了。很抱歉,我真的没有理解你最新的更新:(任何解释都会有帮助的。谢谢:) - ging
Postgreql数据库 - ging
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接