SQL 聚合具有相同 id 的行,辅助列中的特定值

Posted

技术标签:

【中文标题】SQL 聚合具有相同 id 的行,辅助列中的特定值【英文标题】:SQL aggregate rows with same id , specific value in secondary column 【发布时间】:2018-02-09 16:35:30 【问题描述】:

如果出现 status 列中的值之一,我希望过滤掉数据库 (PostgreSQL) 中的行。如果唯一的reference 仅具有等于1status,则想法是对amount 列求和。如果查询还具有2 或任何其他status 的状态,则查询根本不应该SELECTreferencestatus 指的是事务的状态。

当前数据表:

reference | amount | status
   1         100       1       
   2         120       1
   2        -120       2
   3         200       1
   3        -200       2
   4         450       1

结果:

amount | status
  550      1

我已经简化了数据示例,但我认为它很好地说明了我在寻找什么。 我只选择状态为1references 失败。 我试过子查询,使用HAVING子句和其他方法都没有成功。

谢谢

【问题讨论】:

嘿,您在这个阶段有什么疑问? 【参考方案1】:

这是一种使用not exists 对状态为 1 的所有行求和的方法,并且不存在具有相同引用和非 1 状态的其他行。

select sum(amount) from mytable t1
where status = 1
and not exists (
    select 1 from mytable t2
    where t2.reference = t1.reference
    and t2.status <> 1
)

【讨论】:

【参考方案2】:
SELECT SUM(amount)
 FROM table
WHERE reference NOT IN (
 SELECT reference
 FROM table
 WHERE status<>1
)

子查询选择所有必须排除的references,然后主查询汇总除它们之外的所有内容

【讨论】:

【参考方案3】:
select sum (amount) as amount
from (
    select sum(amount) as amount
    from t
    group by reference
    having not bool_or(status <> 1)
) s;
 amount 
--------
    550

【讨论】:

我喜欢使用bool_or聚合函数:) 感谢,但是查询会在具有多个状态的参考文献中产生两个答案(即参考文献 2,3 )。导致所有行的聚合。也许我的示例还不够,并且没有涵盖这里的用例。【参考方案4】:

您可以使用windowed functions 来计算每个组中出现的不同状态的次数:

SELECT SUM(amount) AS amount
FROM (SELECT *,COUNT(*) FILTER(WHERE status<>1) OVER(PARTITION BY reference) cnt
      FROM tc) AS sub
WHERE cnt = 0;

Rextester Demo

【讨论】:

以上是关于SQL 聚合具有相同 id 的行,辅助列中的特定值的主要内容,如果未能解决你的问题,请参考以下文章

如何在特定列中添加具有相同字符串值的行,并且不转换数据框? [重复]

如何删除R中两列中具有相同值但ID不同的行[重复]

获取具有特定数量的重复值的行

如何对特定列中具有相同值的行求和

聚合具有特定值的两行之间的行

SQL - 在列中查找具有特定值组合的行