получить более одного столбца на внутреннем соединении - PullRequest
2 голосов
/ 27 сентября 2011

у меня следующий запрос:

SELECT c.company_id, c.company_title, c.featured, a.address, a.postal_code, pc.city, pc.region,cat.category_title, p.phone
FROM dloc.companies c 
    INNER JOIN dloc.address a ON ( c.address_id = a.address_id  )  
  INNER JOIN dloc.postal_code pc ON ( a.postal_code = pc.postal_code )
  INNER JOIN dloc.company_categories cc ON ( c.company_id = cc.company_id )
  INNER JOIN dloc.categories cat ON ( cc.category_id = cat.category_id )
  INNER JOIN dloc.phones p ON ( c.company_id = p.company_id )

WHERE c.company_title like '%gge%'

все работает просто отлично. единственное ... хорошо. phones содержит более одного номера телефона для некоторых компаний ... и я думаю, я получу только первый ... или случайно, я не уверен Как я могу переписать этот запрос, чтобы он возвращал все телефонные номера для каждой компании?

Ответы [ 4 ]

2 голосов
/ 27 сентября 2011

Учитывая этот запрос, вы должны получить одну строку для каждой строки телефонного номера (для компании).SQL работает как математика / теория отношений / наборов - наличие отношения '-many' означает возвращение нескольких строк (поэтому ваш запрос уже должен выполнить желаемое поведение).

Часто проблема, с которой сталкиваются люди, пишущие запросы, не возникает.не получаю несколько строк - это ограничение желаемой «единственной» строки.

РЕДАКТИРОВАТЬ:

Порядок результатов -
SQL, по соглашению, возвращает вещи неупорядоченные , , если не задан какой-либо явный порядок (через использованиеORDER BY пункта).Вы видите, что «случайные» телефонные номера возвращаются «первыми», потому что СУБД все еще должна считывать / возвращать результаты последовательно;этот порядок определяется во время выполнения (... обычно), когда система выбирает то, что указывает на использование при доступе к данным.Полное взаимодействие довольно сложное (и, вероятно, зависит от поставщика), поэтому просто имейте это в виду:
ЕСЛИ ВЫ НЕ УКАЗЫВАЕТЕ, ЧТОБЫ ЗАКАЗАТЬ ВАШИ РЕЗУЛЬТАТЫ, РЕЗУЛЬТАТЫ ВОЗВРАЩАЮТСЯ В СЛУЧАЙНОМ ПОРЯДКЕ
период .

1 голос
/ 27 сентября 2011

Я бы предложил вам использовать GROUP_CONCAT в поле p.phone.

Несколько соображений:

  • Это похоже на компаниюможет иметь более одного телефона.Но также нет!Таким образом, вы должны изменить INNER JOIN на LEFT JOIN, чтобы принять это во внимание.
  • Похоже, что компания может иметь более одного адреса.Если это так, следует учитывать не только предыдущее соображение, но и заново обработать запрос, чтобы учесть это.
0 голосов
/ 27 сентября 2011

group_concat соберет все номера телефонов в одном столбце.
Добавьте group by для company_id, если вы уверены, что другие значения не указаны более одного раза для каждой компании.
Если нет, поместите эти дубликаты' (из-за отсутствия лучшего слова) значений в group_concat.

SELECT 
  c.company_id
  , c.company_title
  , c.featured
  , a.address
  , a.postal_code
  , pc.city
  , pc.region
  , cat.category_title
  , GROUP_CONCAT(p.phone) as phonenumbers
FROM dloc.companies c 
INNER JOIN dloc.address a ON ( c.address_id = a.address_id  )  
INNER JOIN dloc.postal_code pc ON ( a.postal_code = pc.postal_code )
INNER JOIN dloc.company_categories cc ON ( c.company_id = cc.company_id )
INNER JOIN dloc.categories cat ON ( cc.category_id = cat.category_id )
INNER JOIN dloc.phones p ON ( c.company_id = p.company_id )
WHERE c.company_title like '%gge%'
GROUP BY c.companyid

См .: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

0 голосов
/ 27 сентября 2011

Вы должны получить все телефонные номера для данного идентификатора компании, потому что объединение начинается с создания декартового произведения между двумя таблицами и последующего удаления всех «строк», которые не соответствуют критериям в объединении.

...