Проблема GROUP_CONCAT и LEFT_JOIN — возвращены не все строки

StackOverflow https://stackoverflow.com/questions/1653195

Вопрос

Допустим, моя схема БД выглядит следующим образом:

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 создать строку для этого продукта, даже если существует ЛЕВОЕ ПРИСОЕДИНЕНИЕ.

  1. Это ожидаемое поведение MySQL?
  2. Есть ли способ получить ожидаемый результат, используя 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top