MYSQL: подсчитайте количество строк в одной таблице на основе объединения двух других таблиц

У меня есть три таблицы: Entries, Institution и Doctors. Вот минимальный пример данных таблицы:

ЗАПИСИ

| keyid  | doctorid | 
---------------------
|  1     |    23    |
|  2     |    13    | 
|  3     |    23    | 
|  4     |    13    | 
|  5     |    23    |
|  6     |    42    | 
|  7     |    5     | 

УЧРЕЖДЕНИЕ

| name   |
----------
|  One   |
|  Two   |
|  Three |
|  Four  |
|  Five  |
|  Six   |

ВРАЧИ

| uid      |   inst   | 
-----------------------
|  23      |    Three |
|  13      |    Six   | 
|  3       |    Four  | 
|  42      |    Six   | 
|  5       |    One   |

Что мне нужно знать, так это количество записей, которые у меня есть для каждого учреждения. Однако учреждения связаны с записями через таблицу DOCTORS. Итак, результат в этом случае должен дать мне следующее:

РЕЗУЛЬТАТЫ

| name     | count |
--------------------
| One      |  1    |
| Two      |  0    |
| Three    |  3    |
| Four     |  0    |
| Five     |  0    |
| Six      |  3    |

Я понятия не имею, как даже начать писать этот запрос. Любая помощь будет принята с благодарностью.

Начните с присоединения к 3 столам.

P.Salmon 03.02.2019 14:36

Я уже делал это ранее (ВЫБЕРИТЕ ОТЛИЧНЫЕ i.name, i.uid, r.keyid FROM INSTITUTION AS i, ENTRIES AS r, DOCTORS as d WHERE (i.name = d.inst) AND (d.uid = r .докторид);). Однако я не знаю, как отформатировать это, чтобы получить то, что мне нужно.

aarelovich 03.02.2019 14:40

Не используйте неявные соединения, используйте явные соединения и читайте агрегатные функции mysql.dev.mysql.com/doc/refman/8.0/en/group-by-functions‌​.html

P.Salmon 03.02.2019 14:49

Все еще боретесь? См. meta.stackoverflow.com/questions/333952/…

Strawberry 03.02.2019 15:02

Ага. Прости. Я даже не могу начать писать запрос, который, кажется, делает то, что я хочу. Моя единственная попытка была встречена синтаксической ошибкой, которую я не знаю, как исправить, и я на часах. Я действительно не знаю, как даже начать писать запрос, потому что я не знаю, как заставить COUNT считать то, что я хочу. Итак, я сдаюсь. Я просто делаю запрос, который я предоставил, а затем выполняю внешний цикл for, чтобы подсчитать количество результатов.

aarelovich 03.02.2019 15:06
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
5
36
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это можно решить с помощью агрегированного запроса, который СОЕДИНЯЕТ все три таблицы, например:

SELECT
    i.name,
    COALESCE(COUNT(e.keyid), 0) cnt
FROM
    institution i
    LEFT JOIN doctors d ON d.inst = i.name
    LEFT JOIN entries e ON e.doctorid = d.uid
GROUP BY i.name

Используя ваши образцы данных, этот демо на DB Fiddle возвращает:

| name  | cnt |
| ----- | --- |
| One   | 1   |
| Two   | 0   |
| Three | 3   |
| Four  | 0   |
| Five  | 0   |
| Six   | 3   |

PS: в зависимости от ваших данных вы можете использовать COUNT(DISTINCT e.keyid).

Я сейчас далеко от компьютера. Но мне пришлось поискать COALESCE. Если я правильно понял, вы использовали его только для возврата 0 для тех учреждений, в которых не было записей. Это правильно?

aarelovich 03.02.2019 16:19

@aarelovitch: да, это правильно. Без COALESCE у нас были бы значения NULL.

GMB 03.02.2019 16:25

Так что я, наконец, должен попробовать ваш запрос. Это не работает. И, честно говоря, результаты, которые я получил, не имели никакого смысла. Была возвращена одна строка (и должно было быть возвращено около 5). Кроме того, значение cnt было выше, чем количество строк в таблице entres.

aarelovich 03.02.2019 21:16

@aarelovich: я сделал несколько исправлений в запросе и протестировал его, насколько мне известно, теперь он работает нормально!

GMB 03.02.2019 21:37

СПАСИБО!!! Однако одна маленькая поправка. Я сделал образцы данных. Реальный набор данных был слишком сложен для воспроизведения. Однако запрос по-прежнему дал мне больше результатов, чем было строк в таблице ввода. Именно тогда я понял, что мне нужен DISTINCT в COUNT, чтобы подсчитывать ТОЛЬКО разные записи. Это помогло!!

aarelovich 03.02.2019 21:44

Другие вопросы по теме