【问题标题】:SQL SubquerySQL 子查询
【发布时间】:2010-09-17 09:17:34
【问题描述】:

我有如下所示的 SQL 数据

events
id name         capacity
1  Cooking        10
2  Swimming       20
3  Archery        15

registrants
id  name
1   Jimmy
2   Billy
3   Sally

registrant_event
registrant_id  event_id
     1             3
     2             3
     3             2

我想选择“事件”中的所有字段以及一个附加字段,即当前注册该事件的人数。在这种情况下,射箭有 2 个注册人,游泳有 1 个,烹饪有 0 个。

我想这可以在单个查询中完成,但我不确定语法是否正确。 如何编写查询来获取该数据?

更新:感谢您的精彩回答,你们都摇滚!

【问题讨论】:

    标签: sql database count subquery


    【解决方案1】:
    SELECT e.*, ISNULL(ec.TotalRegistrants, 0) FROM events e LEFT OUTER JOIN
    (
       SELECT event_id, Count(registrant_id) AS TotalRegistrants
       FROM registrant_event
       GROUP BY event_id
    ) ec ON e.id  = ec.event_id
    

    【讨论】:

    【解决方案2】:
    SELECT Events.ID, Events.Name, Events.Capacity, 
           ISNULL(COUNT(Registrant_Event.Registrant_ID), 0)
    FROM Events
    LEFT OUTER JOIN Registrant_Event ON Events.ID = Registrant_Event.Event_ID
    GROUP BY Events.ID, Events.Name, Events.Capacity
    

    【讨论】:

    • GROUP BY Events.ID、Events.Name、Events.Capacity 不正确
    • 在这种情况下使用 GROUP BY 的正确方法是使用子查询。将所有选定的字段放在 GROUP BY 中是一个常见错误。
    • 1) “不正确”与“不会工作”和“不好的风格”是有区别的。 2)由于问题中没有提到数据库,所以不知道数据库是否支持子查询。
    • 子查询是文章的标签之一。
    • 也是题目的标题
    【解决方案3】:
    select d.id1, d.name, d.cappacity, count(d.b_id) as number_of_people
    from (select eve.id1,eve.name,eve.cappacity,re_eve.b_id
         from eve left join re_eve on eve.id1 = re_eve.b_id) d
    group by d.id1, d.name, d.cappacity
    

    【讨论】:

      【解决方案4】:

      我在 Oracle 11g 中对此进行了测试,它似乎可以工作

      SELECT e.id, e.name, e.capacity, COUNT(re.event_id)
      FROM events e
      LEFT JOIN registrant_event re
        ON e.id = re.event_id
      GROUP BY e.id, e.name, e.capacity
      

      【讨论】:

        【解决方案5】:
        select e.id, e.name, e.capacity, IsNull(re.eventCount,0) from events e
        left join (
         select count(event_id) as eventCount, event_id  from registrant_event group by event_id
         ) re 
        on e.id = re.event_id

        【讨论】:

        • 我想你的意思是 count(registrant_id)
        • 我从没想过会这样做,但我看到它会起作用。有什么优势吗?
        • 老实说,我不知道这样做是否有任何好处,但我对此表示怀疑。我就是这样做的,因为这是我们分组的依据。
        【解决方案6】:
        SELECT e.id, count(*) AS NumRegistrants
        FROM events e
        LEFT JOIN registrant_event re ON re.event_id=e.id
        GROUP BY e.id
        

        请注意,对于没有注册人的事件,这将返回 1 而不是 0。要让它显示 0,您必须变得更复杂一些:

        SELECT *,
            (SELECT COUNT(*) FROM registrant_event WHERE event_id=id) AS NumRegistrants
        FROM events
        

        【讨论】:

        • 在包含空值的列/字段上使用计数不会计算它们...例如 COUNT(re.registrant_id)
        • 确实如此。在这些情况下,COUNT(*) 是许多错误的根源。
        【解决方案7】:
        SELECT
          events.*
        , COUNT(registrant_event.registrant_id) AS registrantsCount
        FROM events
        LEFT JOIN registrant_event ON events.id = registrant_event.event_id
        GROUP BY events.id
        

        【讨论】:

        • 如果 events 表中有字段不在 group by 子句中,则会失败。 IE:除了 id 以外的任何东西
        • 这个查询在符合 ANSI 的 SQL 服务器上发出嘶嘶声...包括 ANSI 模式下的 MySQL(以 --ansi 开关开头)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多