用group by编写查询的更好方法

时间:2018-12-31 09:11:03

标签: sql sql-server

我有两个SQL查询来查询电子邮件域计数,如下所示。哪个是更好的方法?

似乎两个查询都返回完全相同的执行计划,但我不明白为什么会这样。

第一

SELECT emaildomain, 
       Count(email) AS Total 
FROM   (SELECT email, 
               Substring(email, Charindex('@', email) + 1, 
               Len(email) - Charindex('@', 
                            email)) 
               AS EmailDomain 
        FROM   [dbo].[tbluser]) A 
GROUP  BY emaildomain 

第二

Select substring(email, charindex('@', Email) + 1,
Len(Email) - charindex('@', Email)) as EmailDomain,
count (Email) as Total
from [dbo].[tblUser]
GROUP BY substring(email, charindex('@', Email) + 1,
Len(Email) - charindex('@', Email))

2 个答案:

答案 0 :(得分:5)

执行计划应该相同。哪个更好取决于多个因素,但都可以。

我想提出另一种选择:

SELECT v.emaildomain, count(*) as total
FROM dbo.tbluser u CROSS APPLY
     (VALUES (substring(u.email, Charindex('@', u.email) + 1, 
                        Len(u.email) - Charindex('@', u.email)
                       ) 
             )
     ) v(EmailDomain) 
GROUP BY vemaildomain ;

APPLY实现了一种称为“横向连接”的东西。这有很多用途。但一种用途是定义不需要子查询/ CTE的新列别名。

请注意,您还可以将逻辑简化为:

     (VALUES ( stuff(u.email, 1, charindex('@', u.email) + 1, '') )
     ) v(EmailDomain) 

答案 1 :(得分:1)

如果两者的执行计划都相同,就我而言,第一个查询比第二个查询更干净,就我个人而言,我更喜欢使用通用表表达式(CTE),但等效于使用派生表。

下次您可以使用此工具共享执行计划: https://www.brentozar.com/pastetheplan/