Проблема GROUP_CONCAT и LEFT_JOIN — возвращены не все строки
-
11-09-2019 - |
Вопрос
Допустим, моя схема БД выглядит следующим образом:
T_PRODUCT
id_product (int, primary)
two entries: (id_product =1) , (id_product =2)
T_USER
id_user (int, primary)
id_product (int, foreign key)
name_user (varchar)
two entries: (id_product=1,name_user='John') , (id_product=1,name_user='Mike')
Если я запущу первый запрос, чтобы получить все продукты и их пользователей (если они есть), я получу следующее:
SELECT T_PRODUCT.id_product, T_USER.name_user
FROM T_PRODUCT
LEFT JOIN T_USER on T_USER.id_product = T_PRODUCT.id_product;
>>
id_product name_user
1 John
1 Mike
2 NULL
Мне кажется хорошо.Теперь, если я хочу то же самое, за исключением того, что мне хотелось бы иметь по одному продукту в строке с объединенными именами пользователей (если есть пользователи, в противном случае NULL):
SELECT T_PRODUCT.id_product, GROUP_CONCAT(T_USER.name_user)
FROM T_PRODUCT
LEFT JOIN T_USER on T_USER.id_product = T_PRODUCT.id_product;
>>
id_product name_user
1 John,Mike
**expected output**:
id_product name_user
1 John,Mike
2 NULL
Если для продукта нет пользователей, GROUP_CONCAT не позволяет MySQL создать строку для этого продукта, даже если существует ЛЕВОЕ ПРИСОЕДИНЕНИЕ.
- Это ожидаемое поведение MySQL?
- Есть ли способ получить ожидаемый результат, используя GROUP_CONCAT или другую функцию?
Решение
О, нашел свой ответ:
Вы никогда не должны забывать ГРУППА ПО пункт при работе с ГРУППА_CONCAT.я пропал без вести GROUP BY T_PRODUCT.id_product
в моем втором запросе.
Оставлю этот вопрос, на случай, если кто-то окажется столь же рассеянным, как я.
Редактировать:
От этот ответ, я решил, что могу также активировать режим SQL ONLY_FULL_GROUP_BY
чтобы заставить MySQL выдавать ошибку в случае, если GROUP BY отсутствует или неверен.
Другие советы
В качестве альтернативы вы можете использовать подзапрос, просто проверьте производительность.
SELECT
T_PRODUCT.id_product,
(SELECT GROUP_CONCAT(T_USER.name_user)
FROM T_USER
WHERE T_USER.id_product = T_PRODUCT.id_product
)
FROM T_PRODUCT