我可以优化这个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秒。