Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以优化这个sql查询吗?_Sql_Sql Server_Sql Server 2005_Optimization - Fatal编程技术网

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

我可以优化这个sql查询吗?,sql,sql-server,sql-server-2005,optimization,Sql,Sql Server,Sql Server 2005,Optimization,下面是我正在尝试做的一个示例查询,它完成了工作,但我觉得子查询并不是最好的方式。有什么建议吗 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.Use

下面是我正在尝试做的一个示例查询,它完成了工作,但我觉得子查询并不是最好的方式。有什么建议吗

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

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

我是否遗漏了一些重要的内容,或者您不能通过单个聚合查询来完成这一点

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

我是否遗漏了一些重要的信息,或者您不能通过一个聚合查询来实现这一点

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

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

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

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

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

我想试试这样的东西:

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

我想试试这样的东西:

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

您可以发布执行计划吗?在我看来,您可以使用sumif success=0然后使用1其他0 endif之类的方法,在一个select中而不是在三个select中对登录进行所有查询。您可以发布执行计划吗?在我看来,您可以使用sumif success=0之类的方法,在一个select中而不是在三个select中对登录进行所有查询1其他0 endif?是的,我的评论就是这个意思。我没有回答,因为我不确定语法。这也是一件好事,因为我弄错了。我很想看看和我的pivot示例相比,它的性能如何。@chaospinion我也很好奇。如果有人有机会进行比较,请与我们分享您的结果。@OMG Ponies嘿,通常情况相反。干杯仅供参考-我刚刚在一台小型生产服务器上运行了此查询。我增加了50000个用户和大约400万个登录记录。djacobson的查询运行了大约6秒钟;从那以后我删除了我的,用了将近50秒。我的回答也花了大约45秒。是的,这就是我评论的意思。我没有回答,因为我不确定语法。这也是一件好事,因为我弄错了。我很想看看和我的pivot示例相比,它的性能如何。@chaospinion我也很好奇。如果有人有机会进行比较,请与我们分享您的结果。@OMG Ponies嘿,通常情况相反。干杯仅供参考-我刚刚在一台小型生产服务器上运行了此查询。我增加了50000个用户和大约400万个登录记录。djacobson的查询运行了大约6秒钟;从那以后我删除了我的,用了将近50秒。回答这个问题也花了大约45秒。