SQL - Displaying entries that are the max of a count?

后端 未结 7 1437
悲&欢浪女
悲&欢浪女 2020-12-01 12:35
CREATE TABLE doctor( patient CHAR(13), docname CHAR(30) );

Say I had a table like this, then how would I display the names of the doctors that have

相关标签:
7条回答
  • 2020-12-01 13:09

    Take both queries and join them together to get the max:

     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 
    
    0 讨论(0)
  • 2020-12-01 13:13

    This should do it for you:

    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)
    
    0 讨论(0)
  • 2020-12-01 13:15

    While using ... HAVING COUNT(*) = ( ...MAX().. ) works:

    • Within the query, it needs almost the same sub-query twice.
    • For most databases, it needs a 2nd level sub-query as MAX( COUNT(*) ) is not supported.

    While using TOP / LIMIT / RANK etc works:

    • It uses SQL extensions for a specific database.

    Also, using TOP / LIMIT of 1 will only give one row - what if there are two or more doctors with the same maximum number of patients?

    I would break the problem into steps:

    Get target field(s) and associated count

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

    Using the above as a 'statement scoped view', join to get the max count row(s)

    WITH x AS
    (
        SELECT docName, COUNT( patient ) AS countX
        FROM doctor
        GROUP BY docName
    )
    SELECT x.docName, x.countX
    FROM x
    INNER JOIN
    (
        SELECT MAX( countX ) AS maxCountX
        FROM x
    ) x2
    ON x2.maxCountX = x.countX
    

    The WITH clause, which defines a 'statement scoped view', effectively gives named sub-queries that can be re-used within the same query.

    The JOIN matches the row(s) of the maximum count of the patients.

    While this solution, using statement scoped views, is longer, it is:

    • Easier to test
    • Self documenting
    • Extendable

    It is easier to test as parts of the query can be run standalone.

    It is self documenting as the query directly reflects the requirement ie the statement scoped view lists the target field(s) and associated count.

    It is extendable as if other conditions or fields are required, this can be easily added to the statement scoped view. eg in this case, the table stucture should be changed to include a doctor-id as a primary key field and this should be part of the results.

    0 讨论(0)
  • 2020-12-01 13:15

    Another alternative using 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)
    
    0 讨论(0)
  • 2020-12-01 13:16

    Here's another alternative that only has one subquery instead of two:

    SELECT docname
    FROM author
    GROUP BY name
    HAVING COUNT(*) = (
        SELECT COUNT(*) AS c
        FROM author
        GROUP BY name
        ORDER BY c DESC
        LIMIT 1
    )
    
    0 讨论(0)
  • 2020-12-01 13:24

    Allowing for any feature in any ISO SQL specification since you did not specify a database product or version, and assuming that the table of patients is called "patients" and has a column called "docname", the following might give you what you wanted:

    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
    
    0 讨论(0)
提交回复
热议问题