如何在 SQL Server 中使用聚合函数

Posted

技术标签:

【中文标题】如何在 SQL Server 中使用聚合函数【英文标题】:How to use aggregate functions in SQL Server 【发布时间】:2020-06-08 05:16:51 【问题描述】:

我有一个客户表的情况,我需要从一个结构为字符串的列中找到文档编号,其中前 4 个字符代表文档的类型(例如,'BILL000000000001'、'PYMT000000000001') .这些文件中的每一个也有一个相应的文件日期。我想用 ma​​x(DocDate) 获取 CustomerNumber 其中 DocTypeBILL 并返回 CustomerNumberDocDate。这部分相当简单,没有任何挑战。

我的问题是一些客户还没有以“BILL”开头的文档。对于那些,我想获取与另一个字符串 XXXX 匹配的 CustomerNumberma​​x(DocDate) 作为前 4 个字符。本质上,我需要使用某种条件表达式来获取 BILL 类型的 CustomerNumberma​​x(DocDate)Customer Numberma​​x(DocDate) 用于 XXXX 类型的记录。问题是客户可能同时存在 BILLXXXX 类型。如果存在 BILL,我想为该客户选择 CustomerNumberma​​x(DocDate)。但是,如果存在 XXXX 类型但没有可用的 BILL 类型文档,我需要 CustomerNumberma​​x(DocDate) 用于类型 XXXX

我曾考虑使用 EXCEPTUNION,但我认为这两个选项都不适合我。这是我的带有EXCEPT的SQL,如果它有帮助的话。

select CustomerNumber, max(DocDate)
FROM Table1
where substring(DocumentNumber,1,4) = 'BILL'
group by CustomerNumber
EXCEPT
select CustomerNumber, max(DocDate)
from Table1
where substring(umDocumentNumber,1,4) = 'MISC'
group by CustomerNumber

【问题讨论】:

select CustomerNumber, max(DocDate) FROM Table1 where substring(DocumentNumber,1,4) IN ( 'BILL','MISC') GROUP BY CustomerNumber ? 样本数据和期望的结果值得解释。 【参考方案1】:

你可以使用聚合做你想做的事:

select CustomerNumber,
       coalesce(max(case when DocumentNumber like 'BILL%' then DocDate end),
                max(DocumentNumber)
               )
from Table1
where DocumentNumber like 'BILL%' or DocumentNumber like 'MISC%'
group by CustomerNumber;

或者使用窗口函数:

select t1.*
from (select t1.*,
             row_number() over (partition by CustomerNumber
                                order by left(DocumentNumber, 4), DocDate desc
                               ) as seqnum
      from Table1 t1
     ) t1
where seqnum = 1;

此方法允许您返回整行以获得最大文档。

【讨论】:

【参考方案2】:

如果我理解您的逻辑,对于具有 BILL 类型记录的客户,您需要 CustomerNumberMAX(DocDate),对于具有 BILL 的任何客户,您还需要 CustomerNumberMAX(DocDate)类型记录不存在。

您的初始结果的UNION 和另一个包含WHERE NOT EXISTS 子句的结果集应该返回您要查找的内容。

SELECT 
   CustomerNumber
    ,max(DocDate)
FROM Table1
WHERE substring(DocumentNumber, 1, 4) = 'BILL'
GROUP BY CustomerNumber

UNION ALL

SELECT 
   CustomerNumber
    ,max(DocDate)
FROM Table1 AS out
WHERE 
  NOT EXISTS (SELECT 1
              FROM Table1 AS in
              WHERE 
                in.CustomerNumber = out.CustomerNumber
                AND
                substring(umDocumentNumber, 1, 4) = 'BILL'
GROUP BY CustomerNumber;

【讨论】:

以上是关于如何在 SQL Server 中使用聚合函数的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server中的聚合函数都有哪些?

在 SQL SERVER 中使用聚合函数时如何同时显示 id 和 name

sql server中啥是聚合函数

PCB MS SQL CLR聚合函数(函数作用,调用顺序,调用次数) CLR说明

SQL Server聚合函数

SQL Server聚合函数与聚合开窗函数