我对SQL Server查询/函数有一个奇怪的行为。
我有一个有3列的表(实际上还有更多的列,但这3列与此任务相关)。列为FileId
、UserId
和TimeCreated
。一个用户可以多次创建同一个FileId
,我想知道,这是最新创建的文件。
我使用WHERE
条款:
WHERE TimeCreated IN (SELECT MAX(TimeCreated)
FROM table
GROUP BY FileId, UserId)
在我看来,这应该是正确的,但对于某些组,即使TimeCreated
不同,它也会返回多行。
以下是一个结果作为示例:
TimeCreated | UserId | FileId
------------------------------------------------------
2016-01-18 00:00:00.000 | UserA | FileA
2016-01-18 06:00:00:000 | UserA | FileA
但它应该只返回具有"2016-01-18 06:00:00:000"作为TimeCreated
值的行。
我不明白出了什么问题,因为有更多的条目,它们有UserA(作为UserId)和FileA(作为FileId),但TimeCreated值不同,但它只返回这两行(所以在某种程度上,它很有效),就像我所说的,对于一些组来说,这是可以的,但有时它返回两行,具有相同的UserId和FileId,但TimeCreate值不同。当这种情况发生时,总是两排,而不是更多。
TimeCreated
是DateTimeOffset(7)
,UserId
和FileId
一样是字符串。也许知道这一点很重要。。。
有人能解释为什么会发生这种情况吗?
您应该使用以下语法:
;WITH CTE as
(
SELECT
*,
row_number() over (partition by FileId, UserId ORDER BY TimeCreated DESC)rn
FROM <table>
)
SELECT * FROM CTE
WHERE rn = 1
问题是内部选择返回了多个值。它为表中的每个组合FileId
和UserID
返回最大值TimeCreated
。
解决这个问题的一种方法是:
...
FROM table t1
INNER JOIN
(
select FileId, UserId, max(TimeCreated) as maxTimeCreated
from table
group by FileId, UserId)
)
t2 ON t1.TimeCreated = t2.maxTimeCreatedAND t1.UserId = t2.USerId AND T1.FileId = t2.FileId
然而,如果你发布你的表结构和想要的结果,有人可能会向你展示一个更好的方法。
您没有按UserId加入子查询,因此较低的TimeCreated可能对应于另一个用户文件。
from table t1
where TimeCreated = (select max(TimeCreated)
from table
where table.UserId = t1.UserId
and table.FileId = t1.FileId )