我有这种结构的表
CREATE TABLE UsersHistory
(
Id INT IDENTITY,
UserID INT,
StatusId INT,
CreateTime DATETIME,
ChangedTime DATETIME
)
INSERT INTO UsersHistory(UserID, StatusId, CreateTime, ChangedTime)
SELECT 1,1,'20150414','20150414' UNION ALL
SELECT 1,2,'20150414','20150415' UNION ALL
SELECT 1,3,'20150414','20150416' UNION ALL
SELECT 2,1,'20150413','20150413' UNION ALL
SELECT 2,3,'20150413','20150416'
和查询
;WITH k AS (
SELECT uh.UserID,MAX(uh.ChangedTime) AS Dt FROM UsersHistory AS uh
WHERE uh.ChangedTime<'20150416'
GROUP BY uh.UserID
)
SELECT k.UserID,uh.StatusId FROM k
INNER JOIN UsersHistory AS uh
ON k.UserID = uh.UserID AND k.Dt = uh.ChangedTime
查询太简单了,不需要更多解释。我想简化我的。 (删除与datetime类型列的连接)。
有任何建议吗?
答案 0 :(得分:1)
您可以ROW_NUMBER()
使用PARTITION
来实现此目的。像这样的东西
;WITH CTE as
(
SELECT UserID, StatusId, CreateTime, ChangedTime,ROW_NUMBER()OVER(PARTITION BY UserID ORDER BY ChangedTime DESC) r
FROM UsersHistory
WHERE ChangedTime < '20150416'
)
SELECT UserID, StatusId FROM CTE
WHERE r = 1
答案 1 :(得分:0)
在SQL Server 2012+中,您可以使用first_value()
:
SELECT uh.UserID,
FIRST_VALUE(uh.StatusId) OVER (PARTITION BY uh.UserId ORDER BY ChangedTIme DESC)
MAX(uh.ChangedTime) AS Dt
FROM UsersHistory AS uh
WHERE uh.ChangedTime < '20150416';
答案 2 :(得分:0)
据我所知,您希望选择具有最大ChangedTime的记录的UserId和StatusId,其中ChangedTime不等于&#39; 20150416&#39;。请尝试此查询:
SELECT
uh.UserId, uh.StatusId
FROM UsersHistory AS uh
WHERE uh.ChangedTime<'20150416'
AND uh.ChangedTime=(SELECT MAX(ChangedTime) FROM UsersHistory
WHERE UserId=uh.UserId);
答案 3 :(得分:0)
您可以在WHERE子句中添加子查询。这样的事情:
SELECT uh.UserID,
MAX(uh.ChangedTime) AS Dt,
uh.StatusId
FROM UsersHistory uh
WHERE uh.ChangedTime < '20150416'
AND uh.ChangedTime=
(
SELECT MAX(ChangedTime)
FROM UsersHistory
WHERE UserId=uh.UserId
)
GROUP BY uh.UserID, uh.StatusId
答案 4 :(得分:0)
使用APPLY
:
Select uh1.UserID, oa.StatusID
From UserHistory uh1
Cross Apply(Select * From (Select Top 1 uh2.StatusID, uh2.Changetime
From UserHistory uh2
Where uh2.UserID = uh1.UserID And uh2.Changetime < '20150416'
Order By uh2.Changetime desc) t where t.Changetime = uh1.Changetime) oa
答案 5 :(得分:0)
SELECT
distinct uh.UserID,
statusid
FROM UsersHistory uh
inner join
(select
UserID,
max(ChangedTime) dt
from UsersHistory
group by UserID) ct
on (ct.UserID=uh.userid and ct.dt=uh.ChangedTime)