我想要查询的是“获取用户的最后致命日志”。当我查询下面的语句时它只返回“username”和“logDate”字段,但我也想得到这个“logDate”的相应行(我的意思是logid,logdata);
SELECT user.username, MAX(log.logDate) FROM user
INNER JOIN log ON user.userid = log.userid
WHERE log.logtype = 'fatal'
GROUP BY user.username
我的用户表;
userid username
-----------------
1 robert
2 ronaldo
日志表;
logid logDate logtype userid logdata
----------------------------------------------------------
1 2016-11-28 19:37:53.000 fatal 1 data
2 2016-11-28 22:37:53.000 fatal 1 data
3 2016-11-28 12:37:53.000 fatal 2 data
答案 0 :(得分:4)
我将使用CROSS APPLY
执行此操作(首选方法并将适当的索引添加到Log
表)
SELECT *
FROM [USER] u
CROSS apply (SELECT TOP 1 *
FROM log l
WHERE u.userid = l.userid
AND l.logtype = 'fatal'
ORDER BY l.logDate DESC) cs
如果log
表非常大,那么在Log表上创建Non Clustered Index
以提高性能
CREATE NONCLUSTERED INDEX NIX_Log_logtype_userid
ON [log] (logtype,userid)
INCLUDE (logid,logDate,logdata)
使用ROW_NUMBER
SELECT *
FROM (SELECT *,
Row_number()OVER(partition BY [USER].username ORDER BY log.logDate DESC) AS rn
FROM [USER]
INNER JOIN log
ON [USER].userid = log.userid
WHERE log.logtype = 'fatal') A
WHERE rn = 1
使用ROW_NUMBER
和TOP 1 with ties
SELECT TOP 1 WITH ties *
FROM [USER]
INNER JOIN log
ON [USER].userid = log.userid
WHERE log.logtype = 'fatal'
ORDER BY Row_number()OVER(partition BY [USER].username ORDER BY log.logDate DESC)
注意:所有查询都会导致两个表中的所有列都选择所需的列
答案 1 :(得分:2)
快速选项是在子查询中获取max logdate。这样,您可以从用户表中选择所需的任何字段,而不必在外部查询中进行聚合。这个问题的唯一问题是你的logdate不需要重复。如果它是一个日期时间,那么这不太可能,但如果它只是一个日期字段,您可能会有重复项。值得一试。
SELECT
u.username
,u.logdate
,u.logid
,u.logdata
FROM user u
INNER JOIN (SELECT
userid
,MAX(logdate) MaxLog
FROM log
WHERE logtype = 'fatal'
GROUP BY userid) l
ON u.userid = l.userid
AND u.logdate = l.MaxLog
答案 2 :(得分:2)
您可以使用ROW_NUMBER
:
a
答案 3 :(得分:0)
WITH MaxLogDate AS (
SELECT user.userid, MAX(log.logDate) logDate FROM user
INNER JOIN log ON user.userid = log.userid
WHERE log.logtype = 'fatal'
GROUP BY user.userid
)
SELECT log.logid, log.logDate, log.logtype, u.userid, u.username
FROM user u
JOIN MaxLogDate m ON u.userid = m.userid
JOIN log ON log.logDate = m.logDate AND log.userid = m.userid
WHERE log.logtype = 'fatal' --This line is optional, may increase the performance.