我有一张这样的表:
id memberId memberType points date
---- ------------ ------------- ----------- ------------
1 1001 type1 5.5 01/01/2015
2 1002 type2 4.2 01/02/2015
3 1002 type2 2.1 01/15/2015
4 1001 type2 1.5 01/15/2015
5 1002 type1 3.6 01/17/2015
我需要创建一个SQL视图,它将显示每个memberId及其最新成员类型的总和,如下所示:
memberId Type totalPoints
----------- -------------- -----------
1001 type2 7.0
1002 type1 9.9
我尝试了以下查询:
SELECT memberId, MAX(memberType) as Type, SUM(points) as totalPoints
FROM dbo.PointsEarning
GROUP BY memberId
但是当然只有最新类型是最大类型才有效。另外我的一些膜类型纯粹是alpha。如果有人能提供最有效的方法,我会很感激,因为我将它用于一个有近30M记录的表。
答案 0 :(得分:1)
答案 1 :(得分:1)
;WITH CTE as
(
SELECT
SUM(points) OVER (PARTITION BY memberId) totalPoints,
ROW_NUMBER() over (PARTITION BY memberId ORDER BY [date] DESC) rn,
id, memberId, memberType, points, [date]
FROM yourtable
)
SELECT
*
FROM CTE
WHERE rn = 1
答案 2 :(得分:0)
在评论中进行对话后,假设没有人手动将值插入您的id列(使用set identity insert
),那么您可以使用它来查找最后一条记录。因此,只需使用max(date)
代替max(id)
:
;WITH cte AS
(
SELECT memberId, MAX(id) as LastId, SUM(points) as totalPoints
FROM dbo.PointsEarning
GROUP BY memberId
)
SELECT cte.memberId, p.memberType, cte.totalPoints
FROM dbo.PointsEarning p
INNER JOIN cte ON(p.Id = cte.Id)
注意:这应该为每个成员提供一条记录,并且应该比第一个版本更快(如果id实际上是表的聚集索引)。
一种方法是使用公用表表达式:
;WITH cte AS
(
SELECT memberId, MAX(date) as LastDate, SUM(points) as totalPoints
FROM dbo.PointsEarning
GROUP BY memberId
)
SELECT memberId, memberType, totalPoints
FROM dbo.PointsEarning p
INNER JOIN cte ON(p.memberId = cte.memberId AND p.date = cte.LastDate)
注意:代码直接在此处编写,未经过测试。可能会有一些错误。
答案 3 :(得分:0)
试试这个:
SELECT p.memberId,
(SELECT p2.memberType
FROM PointsEarning p2
WHERE p.memberid = p2.memberid
AND NOT EXISTS(
SELECT 'NEXT'
FROM PointsEarning p3
WHERE p3.memberid = p2.memberid
AND p3.date > p2.date)
) as Type, SUM(p.points) as totalPoints
FROM dbo.PointsEarning p
GROUP BY p.memberId
答案 4 :(得分:0)
我假设您要为每个组选择该组中最后memberType
的{{1}}。您可以使用子选择:
date