У меня есть следующие таблицы
contacts
╔═══════════╦═══════════╦══════════╦═══════════╗
║ contactId ║ projectId ║ lastName ║ type ║
╠═══════════╬═══════════╬══════════╬═══════════╣
║ 1 ║ 1 ║ Foo ║ architect ║
║ 2 ║ 1 ║ Owner 1 ║ owner ║
║ 3 ║ 1 ║ Owner 2 ║ owner ║
╚═══════════╩═══════════╩══════════╩═══════════╝
projectDetails
╔═══════════╦═════════════╗
║ projectId ║ projectName ║
╠═══════════╬═════════════╣
║ 1 ║ Bar ║
║ 2 ║ Fizz ║
╚═══════════╩═════════════╝
И я пытаюсь выбрать имя проекта, а также всех соответствующих контактных лиц, выполнив поиск по фамилии контактного лица. Код, который я использую для этого:
SELECT `det`.`projectName`, `owner`.`lastName` as `ownerLast`, `architect`.`lastName` as `archLast`,
FROM `projectDetails` as `det`
LEFT JOIN `contacts` as `owner`
ON `owner`.`projectId` = `det`.`projectId` AND `owner`.`type` = "owner"
LEFT JOIN `contacts` as `architect`
ON `architect`.`projectId` = `det`.`projectId` AND `architect`.`type` = "architect"
WHERE `architect`.`lastName` = "Foo"
Это генерирует две строки
╔═════════════╦═══════════╦══════════╗
║ projectName ║ ownerLast ║ archLast ║
╠═════════════╬═══════════╬══════════╣
║ Bar ║ Owner1 ║ Foo ║
║ Bar ║ Owner2 ║ Foo ║
╚═════════════╩═══════════╩══════════╝
Что, я полагаю, имеет смысл, но это не то, что я ищу. Есть ли способ объединить результаты одного типа, например, во что-то вроде
╔═════════════╦════════════════╦══════════╗
║ projectName ║ ownerLast ║ archLast ║
╠═════════════╬════════════════╬══════════╣
║ Bar ║ Owner1, Owner2 ║ Foo ║
╚═════════════╩════════════════╩══════════╝
Кроме того, ваше второе соединение является внутренним, что можно проиллюстрировать, выполнив EXPLAIN EXTENDED [YOUR QUERY], а затем SHOW WARNINGS;.
Да, и ваш запрос явно недействителен, так что вы не совсем правду!
@ Strawberry, я по ошибке оставил запятую в конце моего запроса SELECT. Прости за это. Я, вероятно, сделаю это на php, спасибо за ваш комментарий.






Используйте group_concat()
SELECT `det`.`projectName`, group_concat(`owner`.`lastName`) as `ownerLast`, `architect`.`lastName` as `archLast`,
FROM `projectDetails` as `det`
LEFT JOIN `contacts` as `owner`
ON `owner`.`projectId` = `det`.`projectId` AND `owner`.`type` = "owner"
LEFT JOIN `contacts` as `architect`
ON `architect`.`projectId` = `det`.`projectId` AND `architect`.`type` = "architect"
WHERE `architect`.`lastName` = "Foo"
group by `det`.`projectName`,`architect`.`lastName`
использовать group_concat()
SELECT `det`.`projectName`, group_concat( `owner`.`lastName`) as `ownerLast`, `architect`.`lastName` as `archLast`,
FROM `projectDetails` as `det`
LEFT JOIN `contacts` as `owner`
ON `owner`.`projectId` = `det`.`projectId` AND `owner`.`type` = "owner"
LEFT JOIN `contacts` as `architect`
ON `architect`.`projectId` = `det`.`projectId` AND `architect`.`type` = "architect"
WHERE `architect`.`lastName` = "Foo"
group by `det`.`projectName`,archLast
Это работает как шарм, спасибо. Как бы вы его изменили, если бы хотели проверить, есть ли у ЛЮБОГО типа в таблице contacts повторяющаяся строка. Я попытался добавить group_concat (architect.lastName), а затем также сгруппировать по owner.lastName, но он вернулся к возврату двух строк.
@ConstantineLoukas на самом деле не будет дублироваться, потому что это поле находится в группе по предложению
Извините, я неправильно объяснил. Допустим, у вас было 10 проектов, у некоторых было 2 владельца, у некоторых 2 архитектора, у некоторых 1 владелец и 1 архитектор, а у некоторых только 1 владелец или 1 архитектор. Есть ли способ изменить приведенный выше запрос, чтобы учесть это, или я должен просто запросить все контакты для этого проекта, а затем выполнить любую группировку на уровне приложения с помощью php?
@ConstantineLoukas Вы должны сменить WHERE на AND
Рассмотрите возможность обработки проблем отображения данных в коде уровня представления / уровня приложения, если это у вас есть (например, простой цикл PHP, действующий на упорядоченный массив).