我需要在MSSQL中查询以返回以下结果:
客户ID,用户名,EventDate
根据下表中的最新日期明确表示每个ClientID:
例如:根据上表,返回:
argv[3]
等
正考虑为TABLE创建一个游标:SELECT DISTINCT来自TABLE的ClientId 并循环遍历每个只返回maxdate的条目,但没有想到它 很有效率。
答案 0 :(得分:0)
我的计算机上没有安装MSSQL,所以我无法为您测试这个,但我认为您可以在SQL中添加“ORDERBY ASC eventdate”过滤器,然后只选择第一行来实现您的目标
所以它会像
SELECT DISTINCT ClientId FROM TABLE ORDER BY eventdate
关于这是否更有效......我认为你将不得不查看查询执行计划,看看MSSQL做了什么操作来进行查询,性能可能不如以前那么好一,因为这个SQL正在做一些额外的事情,即排序。
通过这种方法,至少你不必自己考虑有效的排序算法,它可以节省你对算法的思考和耦合代码行的时间:P
答案 1 :(得分:0)
您所描述的内容比人们想象的要复杂得多,主要是因为除了ClientID和EventDate之外还需要UserName。
这应该可行,虽然我没有在本地构建你的架构来测试,所以如果你有任何错误,请告诉我。
SELECT
t1.*
FROM
SomeTable t1
INNER JOIN
(
SELECT
ClientId
MaxEventDate = MAX(EventDate)
FROM
SomeTable
GROUP BY
ClientId
) t2
ON
t1.ClientID = t2.ClientID
AND t1.EventDate = t2.EventDate
...注意:如果你摆脱了UserName,它只是:
SELECT
ClientId
MaxEventDate = MAX(EventDate)
FROM
SomeTable
GROUP BY
ClientId
答案 2 :(得分:0)
您可以使用CTE获取每个客户端的最新访问日期,然后在CTE上重新加入以获取每个客户端的每个最新访问日期的用户名。如果你的表有主键,那么JOIN在性能,可读性和优雅方面会更好。
;WITH latestClientAccess (ClientId, LatestEventDate) AS (
SELECT ClientId, MAX(EventDate)
FROM MyTable
GROUP BY ClientId
)
SELECT t.ClientId, t.UserName, lca.LatestEventDate [EventDate]
FROM MyTable t
INNER JOIN latestClientAccess lca
ON t.ClientId=lca.ClientId
AND t.EventDate=lca.LatestEventDate
可以通过运行下面的脚本来执行上述概念和脚本的快速本地测试。这样,任何查看此响应的人都可以在不必创建任何模式的情况下进行测试。
declare @temp table(ClientId int, EventDate datetime, UserName varchar(20))
insert into @temp
select 1, '2015-11-06 00:00:00', 'user1'
insert into @temp
select 2, '2015-11-06 00:01:00', 'user1'
insert into @temp
select 1, '2015-11-06 00:01:00', 'user2'
insert into @temp
select 1, '2015-11-06 00:03:00', 'user1'
;WITH latestClientAccess (ClientId, LatestEventDate) AS (
SELECT ClientId, MAX(EventDate)
FROM @temp
GROUP BY ClientId
)
SELECT t.ClientId, t.UserName, lca.LatestEventDate [EventDate]
FROM @temp t
INNER JOIN latestClientAccess lca
ON t.ClientId=lca.ClientId
AND t.EventDate=lca.LatestEventDate
修改强>
考虑到您确实拥有主键和具有客户端名称的第二个表,请考虑以下脚本:
;WITH latestClientAccess (ClientId, HistoryId) AS (
SELECT ClientId, MAX(HistoryId)
FROM MyTable
GROUP BY ClientId
)
SELECT ct.ClientName, t.UserName, t.EventDate
FROM MyTable t
INNER JOIN latestClientAccess lca
ON t.HistoryId=lca.HistoryId
INNER JOIN MyClientTable ct
ON t.ClientId=ct.ClientId
用于快速测试最新事件概念(无客户名称):
declare @temp table(HistoryId int, ClientId int, EventDate datetime, UserName varchar(20))
insert into @temp
select 1, 1, '2015-11-06 00:00:00', 'user1'
insert into @temp
select 2, 2, '2015-11-06 00:01:00', 'user1'
insert into @temp
select 3, 1, '2015-11-06 00:01:00', 'user2'
insert into @temp
select 4, 1, '2015-11-06 00:03:00', 'user1'
;WITH latestClientAccess (ClientId, HistoryId) AS (
SELECT ClientId, MAX(HistoryId)
FROM @temp
GROUP BY ClientId
)
SELECT t.ClientId, t.UserName, t.EventDate
FROM @temp t
INNER JOIN latestClientAccess lca
ON t.HistoryId=lca.HistoryId