SQL Server 聚合查询中的示例 ID [关闭]

Posted

技术标签:

【中文标题】SQL Server 聚合查询中的示例 ID [关闭]【英文标题】:Example ID in aggregate queries SQL Server [closed] 【发布时间】:2021-01-29 09:58:56 【问题描述】:

我有一个汇总大量交易数据的查询。原始数据对每个事务都有唯一的 ID,我需要在每个聚合行中都有一个示例 ID。选择哪个 ID 无关紧要,只要 ID 是完整的,这样我们就可以返回并在需要时从原始交易数据中查找单个示例以进行分组。我无法控制原始数据。

例如,这个:

ID                      Group
6457982468798542364879  Group 1
FR65487985412354        Group 1
1564879541356897        Group 2
6548941236584269        Group 2

进入这个:

ExampleID               Group     Volume
6457982468798542364879  Group 1   2
1564879541356897        Group 2   2

我曾尝试使用 MAX 来执行此操作,但是当 ID 包含字母或超过 20 个字符时,它不起作用。我也尝试使用 STRING_AGG,但一直达到字符数限制,而且我只希望每个组都有一个 ID。

数据集很大,因此要考虑效率。我使用的是 SQL Server 2017 版。

【问题讨论】:

向我们展示您的查询... max 应该可以工作。 MAX()MIN() 有什么问题? 您是否要转换为数字或其他内容?那一件事显然会失败。 听起来您将其从 20 个字符的限制转换为 bigint?别。 MAX 将按字母顺序返回最新的字符串,因此无需 【参考方案1】:

如果示例 ID 无关紧要,请选择一个聚合函数,例如 MIN()MAX(),并使用它来显示组中的一个 ID。

【讨论】:

【参考方案2】:

假设数据如下

CREATE TABLE #Test (ID nvarchar(30), Grp nvarchar(10))
INSERT INTO #Test (ID, Grp) VALUES 
(N'6457982468798542364879' ,N'Group 1'),
(N'FR65487985412354'       ,N'Group 1'),
(N'1564879541356897'       ,N'Group 2'),
(N'6548941236584269'       ,N'Group 2')

更新: 基于关于 MAX 等的 cmets,您可以在一个简单的命令中使用它(不要尝试将其 CAST/CONVERT 转换为任何东西,只需单独使用 MAX)。

SELECT  Grp, 
        MAX(ID) AS ExampleID, 
        COUNT(*) AS Volume
FROM    #Test
GROUP BY Grp

我的原始版本(使用 FIRST_VALUE 获取示例行)需要一个窗口函数作为子查询/CTE。但是使用上面的那个,因为它更清晰,更容易维护,并且可能使用更少的处理时间。为了历史的缘故,这是原始的:

; WITH Src AS 
    (SELECT Grp, 
            FIRST_VALUE(ID) OVER (PARTITION BY Grp ORDER BY ID) AS exampleID
    FROM    #Test
    )
SELECT  Grp, 
        ExampleID, 
        COUNT(*) AS Volume
FROM    Src
GROUP BY Grp, 
        ExampleID

这是更新后的db<>fiddle,包含两个示例。

【讨论】:

【参考方案3】:

似乎一种有效的方法是使用 2 个窗口函数:ROW_NUMBER() 消除重复项,COUNT() 获取音量。像这样。

数据

drop table if exists #Test;
go
create table #Test (
  ExampleID     nvarchar(30), 
  Grp           nvarchar(10));
go

INSERT INTO #Test (ExampleID, Grp) VALUES 
(N'6457982468798542364879', N'Group 1'),
(N'FR65487985412354', N'Group 1'),
(N'1564879541356897', N'Group 2'),
(N'6548941236584269', N'Group 2');

查询

with grp_cte as (
    select *, row_number() over (partition by Grp order by (select null)) rn,
              count(*) over  (partition by Grp order by (select null)) cn
    from #Test)
select ExampleID, Grp as [Group], cn Volume
from grp_cte
where rn=1;

输出

ExampleID               Group       Volume
6457982468798542364879  Group 1     2
1564879541356897        Group 2     2

【讨论】:

当一个简单的 group-by 会做到这一点时,为什么要使用 windows 功能/ctes(根据我的回答)? SELECT Grp, MAX(ID) AS ExampleID, COUNT(*) AS Volume【参考方案4】:

只需使用ID。这应该可以完成工作。

SELECT 
   ID AS ExampleID,
   [GROUP],
   COUNT(ID) as VOLUME
FROM MyTable
GROUP BY [GROUP]

【讨论】:

以上是关于SQL Server 聚合查询中的示例 ID [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Sql Server 聚合或数据透视表查询

没有聚合函数的 SQL Server 数据透视查询

SQL Server:查询分组

SQL Server“不能对包含聚合或子查询的表达式执行聚合函数”,但 Sybase 可以

SQL Server rand() 聚合

SQL Server 查询需要从组中提取数据