#sql #mariadb #inner-join #group-concat
#sql #mariadb #внутреннее соединение #group-concat
Вопрос:
В моей базе данных у меня есть следующие таблицы:
People
----------- ------------
| IdPeople | Name |
----------- ------------
| 1 | James |
| 2 | Chris |
----------- ------------
ref
--------- ------------- ------
| People | Color | Code |
--------- ------------- ------
| 1 | 2 | 1 |
| 1 | 1 | 2 |
| 1 | 6 | 3 |
| 2 | 1 | 1 |
| 2 | 6 | 4 |
| 2 | 4 | NULL |
| 2 | 5 | NULL |
--------- ------------- ------
Colors
-------- --------------------
| IdCol | Color |
-------- --------------------
| 1 | Blue |
| 2 | Green |
| 3 | Yellow |
| 4 | Red |
| 5 | Black |
| 6 | White |
-------- --------------------
Codes
-------- ----------------
| IdCode | Code |
-------- ----------------
| 1 | C |
| 2 | JavaScript |
| 3 | Python |
| 4 | HTML |
-------- ----------------
Я хочу объединить все таблицы, чтобы получить что-то вроде этого:
------------ --------------------------- ------------------------------------
| Name | Color | Code |
------------ --------------------------- ------------------------------------
| Chris | Blue, White, Red, Black | C , HTML |
| James | Green, Blue, White | C , JavaScript, Python |
------------ --------------------------- ------------------------------------
Я попытался присоединиться к group_concat следующим образом
SELECT People.Name,
group_concat(Colors.Color separator ", ") AS "Color",
group_concat(Codes.Code separator ", ") AS "Code"
FROM People
INNER JOIN ref ON People.IdPeople=ref.People
INNER JOIN Colors ON ref.Color=Colors.IdCol
INNER JOIN Codes ON ref.Code=Codes.Code
GROUP BY Name;
Однако, поскольку group_concat не возвращает пустые строки, я получаю все, кроме черного и белого в строке Chris. Я не знаю, как это сделать, так что кто-нибудь может мне помочь, пожалуйста?
Комментарии:
1. Какую СУБД вы используете?
2. @jarlh я использую MariaDB в командной строке в Ubuntu.
3. На заметку: оставайтесь последовательными в своем именовании.
IdPeople
это хорошее имя для идентификатора таблицы people. (Однако я бы, вероятно, предпочел использоватьpeople_id
илиid_people
для удобства чтения, независимо от верхнего / нижнего регистра.) Не называйте одно и то жеPeople
вref
таблице. Дайте ему то же имя. Тогда почемуIdCol
? Почему бы и нетIdColor
, потому что это идентификатор цвета в таблице цветов? При более крупной базе данных такое отсутствие соглашения об именовании может стать проблемой.4. @ThorstenKettner спасибо за этот совет. Мои таблицы на самом деле так не называются, я просто переименовал их, чтобы их было легче понять без контекста.
Ответ №1:
Поскольку ref.code
может быть null, необходимо внешнее соединение с таблицей кода : LEFT OUTER JOIN Codes ON ...
.
Полный запрос:
SELECT People.Name,
group_concat(Colors.Color separator ", ") AS "Color",
group_concat(Codes.Code separator ", ") AS "Code"
FROM People
INNER JOIN REF ON People.IdPeople=ref.People
INNER JOIN Colors ON ref.Color=Colors.IdCol
LEFT JOIN Codes ON ref.Code=Codes.Code
GROUP BY Name;