我有一个看起来像这样的表:
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个属性的最新分数。
有更好的解决方案吗?
编辑:
另外,如果我有Date
,UserId
,AttributeId
和Score
,我可以通过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
答案 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