【问题标题】:Use HAVING or WHERE?使用 HAVING 还是 WHERE?
【发布时间】:2021-03-14 22:50:55
【问题描述】:

我对何时使用 HAVING 和何时使用 WHERE 感到困惑。我需要

查找与 /main.html 相关的软件 Debugger 上的所有错误

这是我的查询

select Tickets.TicketID, b.Data
from Bugs b
Inner Join Tickets
On b.TicketID = Tickets.TicketID
Inner Join Softwares
on Software.SoftwareId = Tickets.SoftwareID
where Software.URL = 'http://debugger.com' and Tickets.Title = '/main.html'

注意:这给了我想要的结果 但我想确保我在这里没有遗漏任何重要的东西。也许我应该在这里的某个地方使用 HAVING?

另外为了让查询在大型数据集上表现更好,我在外键上创建了一个索引

create nonclustered index IX_Tickets_SoftwareId
on [dbo].[Tickets] ([SoftwareId])
go
create nonclustered index IX_Bugs_TicketsId
on [dbo].[Bugs] ([TicketsId])

还好吗?

【问题讨论】:

    标签: sql sql-server inner-join where-clause having-clause


    【解决方案1】:

    WHERE 用于在进行任何分组之前过滤记录。 HAVING 用于过滤分组后的值。只有组中的列或表达式可以包含在 HAVING 子句的

    【讨论】:

      【解决方案2】:

      您的查询很好。您想要过滤单个记录,这就是 WHERE 子句的作用。

      HAVING 子句在聚合查询中发挥作用 - 使用 GROUP BY 的查询,其目的是过滤记录组,使用聚合函数(例如 SUM()、@ 987654325@ 等)。这对您的查询没有意义,不使用聚合。

      顺便说一句,我注意到您没有从softwares 表中返回任何内容,因此连接仅用于过滤。在这种情况下,我发现exists 更合适,因为它的目的很明确:

      select t.ticketid, b.data
      from bugs b
      inner join tickets t on b.ticketid = t.ticketid
      where t.title = '/main.html' and exists (
          select 1 
          from softwares s
          where s.softwareid = t.softwareid and s.url = 'http://debugger.com'
      )
      

      为了提高性能,请考虑在softwares(softwareid, url) 上建立索引,以便子查询高效执行。 tickets(ticketid, title) 上的索引也可能会有所帮助。

      【讨论】:

      • 非常感谢。
      • 快速提问,我是否可以在外键上创建索引?目标是使查询在大型数据集上表现更好。假设我在 20 万个软件中有 5 亿个独特的错误?在这里使用“索引”是一个好的解决方案吗?
      • 好的,我需要使用 Include (url) 添加它们并 include (title) 正确吗?
      猜你喜欢
      • 1970-01-01
      • 2019-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多