使用LEFT JOIN查询问题

时间:2012-07-06 08:12:50

标签: sql sql-server-2008 azure-sql-database

要求:从用户登录表中获取登录表格及其最新登录记录中的所有用户提供租户

当前查询

SELECT [USER].UserName , UserLogin.AttemptDate , UserLogin.LogoutDate
FROM [User] LEFT JOIN UserLogin 
ON [User].UserId = UserLogin.UserId 
WHERE  [User].TenantId=3 
ORDER BY UserLogin.LogoutDate desc

问题:重复用户名不明显

4 个答案:

答案 0 :(得分:4)

SELECT
    a.UserName,
    c.AttemptDate,
    c.LogoutDate
FROM
    [User] a
LEFT JOIN
    (
        SELECT UserId, MAX(LogoutDate) AS maxdate
        FROM UserLogin
        GROUP BY UserId
    ) b ON a.UserId = b.UserId
LEFT JOIN
    UserLogin c ON b.UserId = c.UserId AND b.maxdate = c.LogoutDate
WHERE
    a.TenantId = 3
ORDER BY
    c.LogoutDate DESC

此查询具有与DBMS无关的额外优势(User周围的括号除外),并且不依赖于窗口函数或外部变量。

答案 1 :(得分:2)

似乎每个UserId在UserLogin中都有多个匹配项,您必须为UserLogin中的给定UserId设置记录的优先级,并在结果集中选择所需的记录:

SELECT [USER].UserName , x.AttemptDate , .LogoutDate
FROM [User] 
LEFT JOIN 
(
    SELECT  *,
            ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY <PriorityCondition>) Priority
    FROM    UserLogin 
) x

ON [User].UserId = x.UserId AND x.Priority = 1
WHERE  [User].TenantId=3 
ORDER BY x.LogoutDate desc

就像这个例子一样:

DECLARE @User TABLE (UserId INT, UserName VARCHAR(100), TenantId INT)
INSERT @User VALUES (1, 'a', 3), (2, 'b', 3)

DECLARE @UserLogin TABLE (UserId INT, UserName VARCHAR(100), AttemptDate DATETIME, LogoutDate DATETIME)
INSERT @UserLogin VALUES (1, 'a', GETDATE(), GETDATE()), 
(2, 'b', GETDATE(), GETDATE()),
(2, 'b', GETDATE(), DATEADD(DAY, -1, GETDATE()))


SELECT y.UserName , x.AttemptDate , x.LogoutDate
FROM @User y
LEFT JOIN 
(
    SELECT  *,
            ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY LogoutDate DESC) Priority
    FROM    @UserLogin 
) x 
ON y.UserId = x.UserId AND x.Priority = 1
WHERE  y.TenantId=3 
ORDER BY x.LogoutDate DESC

答案 2 :(得分:1)

with cte as(
SELECT [USER].UserId , max(UserLogin.LogoutDate ) [LogoutDate]
FROM [User] JOIN UserLogin 
ON [User].UserId = UserLogin.UserId 
WHERE  [User].TenantId=3 
group by [USER].UserId 
 )
 select U.UserName,L.AttemptDate , L.LogoutDate from cte C , UserLogin L,
 [User] U
 where C.LogoutDate=L.LogoutDate
 and C.UserId=L.UserId
 and U.UserId=L.UserId

答案 3 :(得分:0)

如果我理解正确

SELECT [USER].UserName , UserLogin.AttemptDate , MAX(UserLogin.LogoutDate) FROM [User] LEFT JOIN UserLogin  ON [User].UserId = UserLogin.UserId  WHERE  [User].TenantId=3 ORDER BY UserLogin.LogoutDate desc