代码之家  ›  专栏  ›  技术社区  ›  Mike Florian Doyen

我可以优化这个SQL查询吗?

  •  1
  • Mike Florian Doyen  · 技术社区  · 14 年前

    下面是一个关于我要做什么的示例查询,它完成了任务,但我觉得子查询并不是最好的方法。有什么指针吗?

    SELECT DISTINCT
        u.UserID,   
        (SELECT COUNT(LoginID) FROM Logins WHERE Success = 1 AND UserID = u.UserID) AS Successful,
        (SELECT COUNT(LoginID) FROM Logins WHERE Success = 0 AND UserID = u.UserID) AS Unsuccessful,        
        (SELECT TOP 1 LoginDate FROM Logins WHERE UserID = u.UserID ORDER BY LoginDate DESC) AS LastLogin
    FROM 
        Users u INNER JOIN 
        Logins l ON u.UserID = l.UserID
    

    顺便说一句,上面的例子看起来不需要连接,但是在实际的解决方案中,我会得到一些其他的列…

    3 回复  |  直到 14 年前
        1
  •  6
  •   Dan J    14 年前

    我是否遗漏了一些重要的内容,或者您是否可以对单个聚合查询执行此操作?

    SELECT u.UserID,
        SUM(CASE WHEN Success = 1 THEN 1 ELSE 0 END) AS Successful,
        SUM(CASE WHEN Success = 0 THEN 1 ELSE 0 END) AS Unsuccessful,
        MAX(LoginDate) AS LastLogin
    FROM Users u
    INNER JOIN Logins l on u.UserID = l.UserID
    GROUP BY u.UserID
    
        2
  •  1
  •   ChaosPandion    14 年前

    我会尝试这样的方法:

    declare @Users Table (UserID int)
    declare @Logins Table (LoginID int, UserID int, LoginDate DateTime, Success Bit)
    
    Insert into @Users
    select 1 union select 2
    
    insert into @Logins
    select 1, 1, '2010-10-13 6:00:00', 1
    union
    select 2, 1, '2010-10-13 7:00:00', 0
    union
    select 3, 1, '2010-10-13 8:00:00', 1
    union
    select 4, 2, '2010-10-13 6:00:00', 0
    union
    select 5, 2, '2010-10-13 7:00:00', 1
    union
    select 6, 2, '2010-10-13 9:00:00', 1
    union
    select 7, 2, '2010-10-13 10:00:00', 1
    
    Select    UserID,
              [1] As Successful,
              [0] As Unsuccessful,
              LoginDate As LoginDate
    From (
        SELECT
            u.UserID, 
            l.LoginID,
            l.Success,
            Max(LoginDate) Over (Partition By u.UserID) As LoginDate
        FROM @Users u 
            INNER JOIN @Logins l ON u.UserID = l.UserID
    ) Data Pivot (
        Count(LoginID) For Success In (
            [0], [1]
        )
    ) Result
    
        3
  •  0
  •   Guffa    14 年前

    如果在您的情况下更有效,您可以尝试:

    select
      u.UserID,   
      sum(case when l.Success = 1 then 1 else 0 end) as Successful,
      sum(case when l.Success = 0 then 1 else 0 end) as Unsuccessful,
      max(LoginDate) as LastLogin
    from 
      Users u
      inner join Logins l on l.UserID = u.UserID
    group by
      u.UserId