考虑以下可笑的简化费用数据库表:
|------------------|--------------|--------|
| 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 |
|------------------|--------|
但是,我想知道如何获得相同的结果,但是还有一个 Description 列,它只显示基表的 Description 列中的值聚合组中的第一条记录。例如:
|------------------|--------------|--------|
| Name | Description | Amount |
|------------------|--------------|--------|
| John Smith | Hotel | £210 |
| Claire Jones | Lunch | £170 |
|------------------|--------------|--------|
这显然不是我正在使用的实际数据,但我想知道是否可以这样做?
答案 0 :(得分:3)
没有第一个记录,因为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_VALUE()
还有另一种相当神秘的方式:
SELECT DISTINCT Name,
FIRST_VALUE(Description) OVER (PARTITION BY name ORDER BY ?),
SUM(Amount) OVER (PARTITION BY name)
FROM dbo.Expenses;
这使用FIRST_VALUE()
作为分析函数,但不是窗口函数。
答案 1 :(得分:2)
使用subquery
:
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]
答案 2 :(得分:0)
您还可以使用窗口功能 -
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