每个用户的所有记录和最新记录的SQL总和

时间:2015-09-22 06:57:30

标签: sql-server

我有一张这样的表:

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记录的表。

5 个答案:

答案 0 :(得分:1)

您可以在以下内容中使用带有MOUSEBUTTONUP子句的子查询:

OVER

您可以在 SQL FIDDLE

进行测试

答案 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