SQL选择最后一次出现的唯一属性

时间:2013-04-30 08:53:52

标签: sql sql-server sql-server-2008

我有一个看起来像这样的表:

   Date   | AttributeId | Score |
4/4/2013         1         0.64      
4/6/2013         2         0.35
4/6/2013         1         0.86
4/4/2013         5         0.34
4/4/2013         4         0.23
4/7/2013         3         0.54
4/8/2013         1         0.66

我可以在MS SQL中构造一个查询,这样我只能获得特定的最后一次出现 属性Id。从上面的例子中,查询将返回:

   Date   | AttributeId | Score |     
4/6/2013         2         0.35
4/4/2013         5         0.34
4/4/2013         4         0.23
4/7/2013         3         0.54
4/8/2013         1         0.66

如果有帮助,我知道只有5个AttributeID(1-5)并且它们不会改变。

目前我正在查询最后15条记录(并希望这些记录包含我的所有5个属性),然后在应用程序级别上,提取所有5个属性的最新分数。
有更好的解决方案吗?

编辑:
另外,如果我有DateUserIdAttributeIdScore,我可以通过UserId以某种方式对结果进行分组吗? 当我尝试你的答案时,我看到我只得到最新的结果,无论UserId。{ 我很抱歉,我应该早点提及UserId

编辑2: 我需要为每个用户获取属性的最新分数,并在属性上平均他们的分数。 样本如下所示:

   Date   |  UserId  | AttributeId | Score |
4/4/2013        1           1         0.64      
4/6/2013        1           1         0.35
4/6/2013        2           1         0.86
4/4/2013        1           3         0.34
4/4/2013        2           3         0.23
4/7/2013        2           1         0.54
4/8/2013        1           5         0.69
4/4/2013        2           4         0.27
4/7/2013        2           2         0.54
4/9/2013        1           4         0.66
4/9/2013        2           2         0.58
4/10/2013       1           4         0.66
4/9/2013        1           2         0.33
4/11/2013       2           5         0.10

第一个结果如下:

   Date   |  UserId  | AttributeId | Score |
4/6/2013        1           1         0.64      
4/9/2013        1           2         0.33
4/4/2013        1           3         0.34
4/10/2013       1           4         0.66
4/8/2013        1           5         0.69
4/7/2013        2           1         0.86
4/9/2013        2           2         0.58
4/4/2013        2           3         0.23
4/4/2013        2           4         0.27
4/11/2013       2           5         0.10

平均得分UserId之后的最后一个结果:

UserId | AverageScore |
   1           0.532     
   2           0.408 

2 个答案:

答案 0 :(得分:4)

SELECT  *
FROM    (
        SELECT  *,
                ROW_NUMBER() OVER (PARTITION BY attributeId ORDER BY [date] DESC) rn
        FROM    mytable
        ) q
WHERE   rn = 1

如果你有一个固定的列表,但有一些属性(或带有它们的表),这个查询可能会更有效:

SELECT  *
FROM    attribute a
OUTER APPLY
        (
        SELECT  TOP 1
                [date], score
        FROM    score s
        WHERE   attributeId = a.id
        ORDER BY
                [date] DESC
        ) s

创建索引:

CREATE INDEX
        ix_score_attribute_date__score
ON      score (attributeId, date)
INCLUDE (score)

让此查询快速运行。

<强>更新

要选择每位用户的最新分数的平均值,请使用:

SELECT  userId, AVG(score)
FROM    (
        SELECT  userId, score
        FROM    (
                SELECT  *
                        ROW_NUMBER() OVER (PARTITION BY userId, attributeId ORDER BY [date] DESC) rn
                FROM    score
                ) s
        WHERE   rn = 1
        ) q
GROUP BY
        userId

答案 1 :(得分:1)

WITH records
AS
(
    SELECT  [Date], AttributeId, Score,
            DENSE_RANK() OVER (PARTITION BY AttributeId ORDER BY [Date] DESC) rn
    FROM    TableName
)
SELECT  [Date], AttributeId, Score
FROM    records
WHERE   rn = 1