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
仅具有等于1
的status
,则想法是对amount
列求和。如果查询还具有2
或任何其他status
的状态,则查询根本不应该SELECT
和reference
。 status
指的是事务的状态。
当前数据表:
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
我已经简化了数据示例,但我认为它很好地说明了我在寻找什么。
我只选择状态为1
的references
失败。
我试过子查询,使用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
)
子查询选择所有必须排除的reference
s,然后主查询汇总除它们之外的所有内容
【讨论】:
【参考方案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 的行,辅助列中的特定值的主要内容,如果未能解决你的问题,请参考以下文章