【问题标题】:SQL - Displaying entries that are the max of a count?SQL - 显示最大计数的条目?
【发布时间】:2011-07-06 19:20:41
【问题描述】:
CREATE TABLE doctor( patient CHAR(13), docname CHAR(30) );

假设我有一张这样的表格,那么我将如何显示患者最多的医生的姓名?就像如果最多三个,两个医生有三个病人,那么我会显示他们两个的名字。

这将获得最大的患者数:

SELECT MAX(count) 
FROM (SELECT COUNT(docname) FROM doctor GROUP BY docname) a;

这是所有医生以及他们有多少病人:

SELECT docname, COUNT(docname) FROM doctor GROUP BY name;

现在我不知道如何将它们组合起来以仅列出拥有最多患者的医生的姓名。

谢谢。

【问题讨论】:

  • 什么数据库产品和版本?
  • 正如@Thomas 建议的那样,如果不知道我们正在使用什么数据库,就很难提供帮助。
  • 您将患者表命名为“作者”? “患者”表的架构是什么样的?
  • 我假设这是 SQL Server,如果不告诉我。
  • @Stewage - 您的医生表包含有关患者的信息?

标签: sql group-by


【解决方案1】:

获取两个查询并将它们连接在一起以获得最大值:

 SELECT
      docName,
      m.MaxCount
    FROM
      author
    INNER JOIN
     (
      SELECT 
            MAX(count)  as MaxCount,
            docName
      FROM 
            (SELECT 
                  COUNT(docname) 
             FROM 
                  doctor 
             GROUP BY 
                  docname
            )
      ) m ON m.DocName = author.DocName 

【讨论】:

    【解决方案2】:

    这应该为你做:

    SELECT docname
    FROM doctor
    GROUP BY docname
    HAVING COUNT(patient)=
        (SELECT MAX(patientcount) FROM
            (SELECT docname,COUNT(patient) AS patientcount
             FROM doctor
             GROUP BY docname) t1)
    

    【讨论】:

    • 我真的很喜欢这个。这更像是我试图做的,除了我使用了 where 子句。我只是无法完全正确的格式。
    【解决方案3】:

    这是另一种选择,只有一个子查询而不是两个:

    SELECT docname
    FROM author
    GROUP BY name
    HAVING COUNT(*) = (
        SELECT COUNT(*) AS c
        FROM author
        GROUP BY name
        ORDER BY c DESC
        LIMIT 1
    )
    

    【讨论】:

    • 抱歉恢复了一个 8 年前的帖子,但是如果多个医生的最大患者人数相同怎么办?这不会只返回第一个吗?
    【解决方案4】:

    允许任何 ISO SQL 规范中的任何功能,因为您没有指定数据库产品或版本,并假设患者表称为“患者”并且有一个名为“docname”的列,以下可能会为您提供你想要的:

    With PatientCounts As
        (
        Select docname
            , Count(*) As PatientCount
        From patient
        Group By docname
        )
        , RankedCounts As
        (
        Select docname, PatientCount
            , Rank() Over( Order By PatientCount ) As PatientCountRank
        From PatientCounts
        )
    Select docname, PatientCount, PatientCountRank
    From RankedCounts 
    Where PatientCountRank = 1
    

    【讨论】:

      【解决方案5】:

      应该这样做。

      SELECT docname, COUNT(*) FROM doctor GROUP BY name HAVING COUNT(*) = 
          (SELECT MAX(c) FROM
              (SELECT COUNT(patient) AS c
               FROM doctor
               GROUP BY docname))
      

      另一方面,如果您只需要第一个条目,那么

      SELECT docname, COUNT(docname) FROM doctor 
      GROUP BY name 
      ORDER BY COUNT(docname) DESC LIMIT 1;
      

      【讨论】:

      • 第一个真的很整洁。我必须习惯以这种心态思考。一次“组合”一件事情:首先是每组的计数,然后是总体上的最大值,然后再次分组并找到计数等于最大值的行。不错。
      【解决方案6】:

      虽然使用 ... HAVING COUNT(*) = ( ...MAX().. ) 有效:

      • 在查询中,需要两次几乎相同的子查询。
      • 对于大多数数据库,它需要一个二级子查询作为 MAX( COUNT(*) ) 不支持。

      虽然使用 TOP / LIMIT / RANK 等有效:

      • 它使用特定数据库的 SQL 扩展。

      另外,使用 TOP / LIMIT 为 1 只会给出一行 - 如果有两个或多个医生的最大患者数相同怎么办?

      我会将问题分解为几个步骤:

      获取目标字段和相关计数

      SELECT docName, COUNT( patient ) AS countX
      FROM doctor
      GROUP BY docName
      

      将上述内容用作“语句范围视图”,使用它来获取最大行数

      WITH x AS
      (
          SELECT docName, COUNT( patient ) AS countX
          FROM doctor
          GROUP BY docName
      )
      SELECT x.docName, x.countX
      FROM x
      WHERE x.countX = ( SELECT MAX( countX ) FROM x )
      

      定义“语句范围视图”的 WITH 子句有效地提供了可在同一查询中重复使用的命名子查询。

      虽然这个使用语句范围视图的解决方案更长,但它是:

      • 更容易测试
      • 自我记录
      • 可扩展

      由于部分查询可以独立运行,因此更容易测试。

      它是自我记录的,因为查询直接反映了需求 即语句范围视图列出了目标字段和相关计数。

      它是可扩展的,就像需要其他条件或字段一样,这可以很容易地添加到语句范围视图中。 例如,在这种情况下,表结构应更改为包含一个医生 ID 作为主键字段,这应该是结果的一部分。

      【讨论】:

      • 嗨,很好的答案,我唯一的问题是关于最后一部分。这里的 INNER JOIN 有什么意义?为什么不简单地 SELECT x.docName, x.countX FROM x WHERE x.Count(x) == (SELECT MAX(countX) FROM x)
      • @Hlib Pylypets 是的,你是对的。答案已编辑以反映您的改进。谢谢
      【解决方案7】:

      使用CTE的另一种选择:

      with cte_DocPatients
      as
      (
      select docname, count(*) as patientCount
      from doctor
      group by docname
      )
      select docname, patientCount from 
      cte_DocPatients where
      patientCount = (select max(patientCount) from cte_DocPatients)
      

      【讨论】:

        【解决方案8】:

        这将为您提供每位医生的姓名和治疗患者的相应数量

        SELECT docname, COUNT(docname) as TreatingPatients FROM doctor
        WHERE docname = docname
        GROUP BY docname
        

        【讨论】:

        • 这将为您提供每位医生姓名和相应的治疗患者人数。
        猜你喜欢
        • 2015-06-25
        • 2022-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-11
        • 1970-01-01
        • 2014-03-14
        • 2014-05-07
        相关资源
        最近更新 更多