SQL - Отображение записей, которые являются максимальным количеством? - PullRequest
12 голосов
/ 01 марта 2011
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;

Теперь я не могу понять, как их объединить, чтобы перечислить только имена врачей, у которых максимальное количество пациентов.

Спасибо.

Ответы [ 7 ]

17 голосов
/ 09 января 2013

Это должно сделать это.

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;
8 голосов
/ 01 марта 2011

Это должно сделать это для вас:

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)
3 голосов
/ 01 марта 2011

Вот еще одна альтернатива, у которой есть только один подзапрос вместо двух:

SELECT docname
FROM author
GROUP BY name
HAVING COUNT(*) = (
    SELECT COUNT(*) AS c
    FROM author
    GROUP BY name
    ORDER BY c DESC
    LIMIT 1
)
2 голосов
/ 01 марта 2011

Если учесть любую функцию в любой спецификации 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
1 голос
/ 06 октября 2017

При использовании ... HAVING COUNT (*) = (... MAX () ..) работает:

  • В запросе требуется почти один и тот же подзапрос дважды.
  • Для большинства баз данных требуется подзапрос 2-го уровня как 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
INNER JOIN
(
    SELECT MAX( countX ) AS maxCountX
    FROM x
) x2
ON x2.maxCountX = x.countX

Предложение WITH, которое определяет «представление в области оператора», фактически дает именованные подзапросы, которые можно повторно использовать в том же запросе.

JOIN соответствует ряду (ам) максимального количества пациентов.

Хотя это решение, с использованием представлений в рамках оператора, длиннее, оно составляет:

  • Проще проверить
  • Самодокументирование
  • Выдвижная

Это проще для тестирования, так как части запроса могут выполняться автономно.

Самодокументируется, так как запрос напрямую отражает требование т. е. представление в области действия оператора перечисляет целевое поле (поля) и соответствующее количество.

Его можно расширять, как если бы требовались другие условия или поля, его можно легко добавить в представление области оператора. например, в этом случае структура таблицы должна быть изменена, чтобы в качестве первичного ключевого поля был указан идентификатор доктора, и это должно быть частью результатов.

1 голос
/ 01 марта 2011

Возьмите оба запроса и соедините их вместе, чтобы получить максимум:

 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 голосов
/ 08 ноября 2017

Другая альтернатива с использованием 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...