Sql 从聚合查询中组中的第一条记录获取值
考虑以下可笑的简化费用数据库表:Sql 从聚合查询中组中的第一条记录获取值,sql,sql-server,aggregate-functions,Sql,Sql Server,Aggregate Functions,考虑以下可笑的简化费用数据库表: |------------------|--------------|--------| | Name | Description | Amount | |------------------|--------------|--------| | John Smith | Hotel | £100 | | John Smith | Evening meal | £30 | | Clai
|------------------|--------------|--------|
| Name | Description | Amount |
|------------------|--------------|--------|
| John Smith | Hotel | £100 |
| John Smith | Evening meal | £30 |
| Claire Jones | Lunch | £20 |
| John Smith | Travel | £80 |
| Claire Jones | Hotel | £150 |
|------------------|--------------|--------|
使用SQL
SELECT [Name], SUM([Amount])
FROM [dbo].[Expenses]
GROUP BY [Name]
我可以得到结果
|------------------|--------|
| John Smith | £210 |
| Claire Jones | £170 |
|------------------|--------|
但是,我想知道如何才能获得相同的结果,但需要一个额外的描述列,该列仅显示聚合组中第一条记录的基表描述列中的值。例如:
|------------------|--------------|--------|
| Name | Description | Amount |
|------------------|--------------|--------|
| John Smith | Hotel | £210 |
| Claire Jones | Lunch | £170 |
|------------------|--------------|--------|
这显然不是我正在处理的实际数据,但我想知道是否有可能做到这一点?使用
子查询
:
SELECT [Name], SUM([Amount]) Amount,
(SELECT TOP 1 Description
FROM [dbo].[Expenses]
WHERE Name = e.Name
ORDER BY Name) Description
FROM [dbo].[Expenses] e
GROUP BY [Name]
使用
子查询
:
SELECT [Name], SUM([Amount]) Amount,
(SELECT TOP 1 Description
FROM [dbo].[Expenses]
WHERE Name = e.Name
ORDER BY Name) Description
FROM [dbo].[Expenses] e
GROUP BY [Name]
没有第一条记录,因为SQL表表示无序数据 因此,可以在列中使用排序。在您的情况下,这可能是:
SELECT Name, MIN(Description), SUM(Amount)
FROM dbo.Expenses
GROUP BY Name;
如果有排序列,则可以使用条件聚合:
SELECT Name,
MAX(CASE WHEN seqnum = 1 THEN Description END),
SUM(Amount)
FROM (SELECT e.*,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ?) as seqnum
FROM dbo.Expenses e
) e
GROUP BY Name;
?
是排序列的占位符
使用第一个值()
还有另一种相当神秘的方法:
这使用了
FIRST\u VALUE()
,该函数可用作分析函数,但不是窗口函数。没有第一条记录,因为SQL表表示无序数据
因此,可以在列中使用排序。在您的情况下,这可能是:
SELECT Name, MIN(Description), SUM(Amount)
FROM dbo.Expenses
GROUP BY Name;
如果有排序列,则可以使用条件聚合:
SELECT Name,
MAX(CASE WHEN seqnum = 1 THEN Description END),
SUM(Amount)
FROM (SELECT e.*,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY ?) as seqnum
FROM dbo.Expenses e
) e
GROUP BY Name;
?
是排序列的占位符
使用第一个值()
还有另一种相当神秘的方法:
这将使用作为分析函数提供的
第一个值()
,但不是窗口函数。您也可以使用窗口函数-
SELECT [Name],
SUM([Amount]) OVER (PARTITION BY [Name]) as total_amount,
ROW_NUMBER() OVER (PARTITION BY [Name] ORDER BY some_column) as row_num
FROM [dbo].[Expenses]
WHERE row_num = 1
您还可以使用窗口功能-
SELECT [Name],
SUM([Amount]) OVER (PARTITION BY [Name]) as total_amount,
ROW_NUMBER() OVER (PARTITION BY [Name] ORDER BY some_column) as row_num
FROM [dbo].[Expenses]
WHERE row_num = 1