Как получить правильный результат с JOIN в SQL? - PullRequest
1 голос
/ 21 сентября 2019

Я хотел получить список значков с помощью issued times.
Это краткая информация о моих таблицах.

таблица Badge:

+----+-----------+
| id |  name     |
+----+-----------+
|  1 | professor |
|  2 | campaign  |
|  3 | test      |
+----+-----------+

таблица issue_history:

+----+-----------+--------+
| id | badge_id  |   ts   |
+----+-----------+--------+
|  1 |        1  |  0908  |
|  2 |        1  |  0909  |
|  3 |        3  |  0909  |
+----+-----------+--------*

Чтобы получить результат, я использовал LEFT JOIN.

SELECT
    b.id,
    b.name,
    COUNT(*) AS issued_times
FROM
    badge b
LEFT JOIN
    issue_history h
ON
    b.id = h.badge_id
GROUP BY
    b.id

Я ожидал результат, как показано ниже

+----+-----------+--------------+
| id |  name     | issued_times |
+----+-----------+--------------+
|  1 | professor |            2 |
|  2 | campaign  |            0 |
|  3 | test      |            1 |
+----+-----------+--------------+

Но я получил неправильный результат

+----+-----------+--------------+
| id |  name     | issued_times |
+----+-----------+--------------+
|  1 | professor |            2 |
|  2 | campaign  |            1 |
|  3 | test      |            1 |
+----+-----------+--------------+

Как видите, время выдачи значка campaign равно 0.
Но результат показывает его значение как 1.
Как я могу исправить эту проблему?

1 Ответ

2 голосов
/ 21 сентября 2019

Проблема здесь в том, что Count(*) считает все строки в определенной группе.Теперь, даже если у вас нет какой-либо строки истории для определенного значка, у вас все равно останется одна строка для значка, соответствующего базовой таблице badge.Вот почему вы получили счет как 1.

Чтобы сосчитать строки истории, вам нужно Count() badge_id из таблицы истории.Таким образом, если в таблице истории нет подходящей строки, badge_id в правой части таблицы будет NULL и COUNT(NULL) = 0:

SELECT
    b.id,
    b.name,
    COUNT(h.badge_id) AS issued_times
FROM
    badge b
LEFT JOIN
    issue_history h
ON
    b.id = h.badge_id
GROUP BY
    b.id, 
    b.name

Обратитесь к этому официальному документу MySQL для дальнейшего понимания: https://dev.mysql.com/doc/refman/8.0/en/counting-rows.html

Кроме того, ваше GROUP BY использование было недействительным;Я добавил b.name в GROUP BY, чтобы он был действительным.Проверьте это, чтобы получить понимание: https://stackoverflow.com/a/34115425/2469308

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...