SQL - 在 having 子句中对结果进行分组和过滤后,如何对一列求和?
SQL - How can I sum up a column after the results have been grouped and filtered in the having clause?
这是我当前的查询:objective 是查找在首次存款后 30 天内收到至少 500 美元存款的账户。一些帐户已关闭并重新打开,因此 'WHERE' 子句的第一行。
select Deposits.accountNumber,
min(Deposits.transDate) as "first deposit",
Deposits.transDate,
CAST(DATEADD(d,30,min(Deposits.transDate)) as date) as "30 days",
sum(Deposits.amount) as "sum",
Deposits.amount,
Members.accountOpenDate
from Deposits
inner join Members on Deposits.accountNumber = members.accountNumber
where Deposits.transDate >= members.accountOpenDate
and Deposits.accountNumber = 123456
group by Deposits.accountNumber
having Deposits.transDate between min(Deposits.transDate) and DATEADD('d',30,min(Deposits.transDate))
and sum(Deposits.amount) >= 500
我 运行 遇到的问题是 HAVING 语句的最后一行:
and sum(Deposits.amount) >= 500
包括该帐户的所有交易,就好像没有 'HAVING' 子句一样。它考虑了从 'HAVING':
的第一行排除的交易
having Deposits.transDate between min(Deposits.transDate) and DATEADD('d',30,min(Deposits.transDate))
这是我的数据(未按帐号分组):
accountNumber amount sum
123456 0 ,500
123456 ,500
123456 ,500
这就是我想要达到的目标:
accountNumber amount sum
123456 0 0
123456 0
123456 0
提前致谢。我的 DBMS 是 Intersystems-Cache。 link 可以找到他们的参考 Here。
您可以尝试类似的方法:
select filtered.accountNumber,
min(filtered.transDate) as "first deposit",
filtered.transDate,
CAST(DATEADD(d,30,min(filtered.transDate)) as date) as "30 days",
sum(filtered.amount) as "sum",
filtered.amount,
filtered.accountOpenDate
from
(
select * from Deposits
inner join Members on Deposits.accountNumber = members.accountNumber
where Deposits.transDate >= members.accountOpenDate
and Deposits.accountNumber = 123456
having Deposits.transDate between min(Deposits.transDate) and DATEADD('d',30,min(Deposits.transDate))
) as filtered
group by filtered.accountNumber
having sum(filtered.amount) >= 500
对于这样的查询,您首先要应用 transDate 条件过滤数据,然后您可以对金额的总和进行过滤
我们需要澄清:
1. 你显示的3笔交易都是30天内window吗?如果是,则总数不到 500 美元。所以,应该跳过这个帐户。
2.既然$6500是所有trans的总和大于open date,为什么还要计算呢?你只关心30天window.
除此之外,我认为断开连接是HAVING子句中的日期计算。您在 SELECT 中使用 MIN,但在 HAVING 中使用完全不同的聚合日期计算。我认为您应该从 HAVING 中取出计算并将其作为 WHERE 的一部分。
当然,一旦你这样做了,你就必须从 SELECT 中取出 MIN。
这是我当前的查询:objective 是查找在首次存款后 30 天内收到至少 500 美元存款的账户。一些帐户已关闭并重新打开,因此 'WHERE' 子句的第一行。
select Deposits.accountNumber,
min(Deposits.transDate) as "first deposit",
Deposits.transDate,
CAST(DATEADD(d,30,min(Deposits.transDate)) as date) as "30 days",
sum(Deposits.amount) as "sum",
Deposits.amount,
Members.accountOpenDate
from Deposits
inner join Members on Deposits.accountNumber = members.accountNumber
where Deposits.transDate >= members.accountOpenDate
and Deposits.accountNumber = 123456
group by Deposits.accountNumber
having Deposits.transDate between min(Deposits.transDate) and DATEADD('d',30,min(Deposits.transDate))
and sum(Deposits.amount) >= 500
我 运行 遇到的问题是 HAVING 语句的最后一行:
and sum(Deposits.amount) >= 500
包括该帐户的所有交易,就好像没有 'HAVING' 子句一样。它考虑了从 'HAVING':
的第一行排除的交易having Deposits.transDate between min(Deposits.transDate) and DATEADD('d',30,min(Deposits.transDate))
这是我的数据(未按帐号分组):
accountNumber amount sum
123456 0 ,500
123456 ,500
123456 ,500
这就是我想要达到的目标:
accountNumber amount sum
123456 0 0
123456 0
123456 0
提前致谢。我的 DBMS 是 Intersystems-Cache。 link 可以找到他们的参考 Here。
您可以尝试类似的方法:
select filtered.accountNumber,
min(filtered.transDate) as "first deposit",
filtered.transDate,
CAST(DATEADD(d,30,min(filtered.transDate)) as date) as "30 days",
sum(filtered.amount) as "sum",
filtered.amount,
filtered.accountOpenDate
from
(
select * from Deposits
inner join Members on Deposits.accountNumber = members.accountNumber
where Deposits.transDate >= members.accountOpenDate
and Deposits.accountNumber = 123456
having Deposits.transDate between min(Deposits.transDate) and DATEADD('d',30,min(Deposits.transDate))
) as filtered
group by filtered.accountNumber
having sum(filtered.amount) >= 500
对于这样的查询,您首先要应用 transDate 条件过滤数据,然后您可以对金额的总和进行过滤
我们需要澄清: 1. 你显示的3笔交易都是30天内window吗?如果是,则总数不到 500 美元。所以,应该跳过这个帐户。 2.既然$6500是所有trans的总和大于open date,为什么还要计算呢?你只关心30天window.
除此之外,我认为断开连接是HAVING子句中的日期计算。您在 SELECT 中使用 MIN,但在 HAVING 中使用完全不同的聚合日期计算。我认为您应该从 HAVING 中取出计算并将其作为 WHERE 的一部分。
当然,一旦你这样做了,你就必须从 SELECT 中取出 MIN。