MySQL объединяет таблицу с несколькими строками - PullRequest
2 голосов
/ 22 августа 2011

У меня есть несколько таблиц, которые я объединил и хотел бы присоединиться к таблице с несколькими столбцами. Мой текущий запрос выглядит следующим образом:

select
    usrs.firstname, usrs.middleNames, usrs.surname,
    if (usrs.sex=0,'Male','Female') as sex,
    usrs.DOB,
   (YEAR(CURDATE())-YEAR(usrs.DOB)) - (RIGHT(CURDATE(),5)<RIGHT(usrs.DOB,5)) AS age,
    birth.townName AS 'birthTown', birth.regionName AS 'birthRegion', birth.countryName AS 'birthCountry',
    location.townName AS 'curTown', location.regionName AS 'curRegion', location.countryName AS 'curCountry',
    usrs.email, emails.email AS 'alternateEmail',
    numbers.number,
    usrs.website,
    usrs.aboutMe,
    family.mother, family.father, family.partner, marital.status, family.aboutFamily,
    children.name AS 'childsName'
from ch09.tbl_users usrs
LEFT JOIN vw_town_region_country birth ON birth.townID = usrs.birthPlace
LEFT JOIN vw_town_region_country location ON location.townID = usrs.currentLocation
LEFT JOIN tbl_alternate_emails emails ON emails.userID = usrs.id
LEFT JOIN tbl_contact_numbers numbers ON numbers.userID = usrs.id
LEFT JOIN tbl_family family ON family.userID = usrs.id
LEFT JOIN tbl_marital_status marital ON family.maritalStatusID = marital.id
LEFT JOIN tbl_children children ON family.id = children.familyID

Я поставил весь свой запрос, это может быть немного неправильным или более чистым способом сделать это. Проблема связана с tbl_children, так как это «один ко многим», это приводит к нескольким строкам для одного пользователя для каждого дочернего элемента, который есть у пользователя в таблице tbl_children.

Итак, мои результаты:

userID:1 firstName middleNames surname ....... childsName
userID:1 firstName middleNames surname ....... childsName
userID:1 firstName middleNames surname ....... childsName

Я бы предпочел:

userID:1 firstName middleNames surname ....... childsName childsName2 childsName3

Возможно ли это как-то сделать через соединение? Очевидно, что для меня неприемлемо иметь несколько записей для каждого пользователя в представлении.

Ответы [ 2 ]

1 голос
/ 22 августа 2011

Для этого вы можете использовать функцию GROUP_CONCAT в сочетании с GROUP BY. GROUP_CONCAT позволяет объединять значения из столбца путем их объединения. Обратите внимание, что это даст вам не столбец для каждого дочернего элемента, а один столбец со строкой, содержащей все имена.

EDIT; ваш запрос станет примерно таким:

select
    usrs.firstname, usrs.middleNames, usrs.surname,
    if (usrs.sex=0,'Male','Female') as sex,
    usrs.DOB,    (YEAR(CURDATE())-YEAR(usrs.DOB)) - (RIGHT(CURDATE(),5)<RIGHT(usrs.DOB,5)) AS age,
    birth.townName AS 'birthTown', birth.regionName AS 'birthRegion', birth.countryName AS 'birthCountry',
    location.townName AS 'curTown', location.regionName AS 'curRegion', location.countryName AS 'curCountry',
    usrs.email, emails.email AS 'alternateEmail',
    numbers.number,
    usrs.website,
    usrs.aboutMe,
    family.mother, family.father, family.partner, marital.status, family.aboutFamily,
    GROUP_CONCAT(children.name SEPERATOR ",") AS 'childsName' 
FROM ch09.tbl_users usrs 
LEFT JOIN vw_town_region_country birth ON birth.townID = usrs.birthPlace 
LEFT JOIN vw_town_region_country location ON location.townID = usrs.currentLocation
LEFT JOIN tbl_alternate_emails emails ON emails.userID = usrs.id 
LEFT JOIN tbl_contact_numbers numbers ON numbers.userID = usrs.id 
LEFT JOIN tbl_family family ON family.userID = usrs.id 
LEFT JOIN tbl_marital_status marital ON family.maritalStatusID = marital.id 
LEFT JOIN tbl_children children ON family.id = children.familyID 
GROUP BY userID
0 голосов
/ 22 августа 2011

Предполагая, что число дочерних элементов неизвестно на момент написания запроса (т. Е. У пользователя может быть 0 или 1 или 5 дочерних элементов), создание такой сводной точки, вероятно, не лучший путь для передачи данных в приложение переднего плана.

В зависимости от того, как вы получаете доступ к данным, вам лучше либо возвращать несколько строк для каждого пользователя, сколько у вас есть, либо извлекать дочерние элементы (и электронные письма и т. Д.) Для каждого пользователя по мере необходимости. Ключевым моментом здесь является их получение только в случае необходимости. Я полагаю, что это известно как Ленивая Загрузка в Объектно-ориентированном мире.

Если вы делаете это, чтобы заполнить какое-либо поле списка, и, следовательно, вам они нужны для каждого пользователя, тогда вы могли бы рассмотреть возможность установить какое-то ограничение на количество дочерних элементов, которые вы будете получать, в зависимости от того, как ваш список будет появляются и затем используют LEFT JOIN s, чтобы получить именно это число для строк, которые вы извлекаете, вместо того, чтобы выполнять круговую поездку на сервер для каждого пользователя.

Другими словами, все зависит. :)

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