SQL - 如何在have子句中对结果进行分组和筛选后,如何汇总列?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL - 如何在have子句中对结果进行分组和筛选后,如何汇总列?相关的知识,希望对你有一定的参考价值。

以下是我目前的疑问:目标是查找在首次存款后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           $100      $6,500
123456           $50       $6,500
123456           $50       $6,500

这就是我想要达到的目标:

accountNumber    amount    sum
123456           $100      $200
123456           $50       $200
123456           $50       $200

提前致谢。我的DBMS是Intersystems-Cache。可以找到他们参考的链接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。您在30天窗口内显示的3笔交易是否全部?如果是,那么总额不到500美元。因此,应该跳过此帐户。 2.由于6500美元是所有trans的总和大于开放日期,为什么甚至计算它?你只关心30天的窗口。

除此之外,我认为断开连接是HAVING子句中的日期计算。您在SELECT中使用MIN,但在HAVING中使用完全不同的聚合日期计算。我认为你应该从HAVING中取出计算并使其成为WHERE的一部分。

当然,一旦你这样做,你将不得不从MIN中取出MIN。

以上是关于SQL - 如何在have子句中对结果进行分组和筛选后,如何汇总列?的主要内容,如果未能解决你的问题,请参考以下文章

Sql

如何在没有“非分组字段x”的情况下对“SUM”进行“HAVING”用于HAVING子句

在SQL语句中同时包含where子句,groupby子句,having子句及聚集函数,将按照怎么样的顺序执行?

在 Codeigniter 中对 WHERE 子句进行分组

SQL之group by 和 having

SQL内容补充