ВНУТРЕННИЙ или ЛЕВЫЙ, объединяющий несколько записей таблицы в одну строку - PullRequest
0 голосов
/ 02 апреля 2010

Телефонный столик

+----------------+-------------+
| Field          | Type        |
+----------------+-------------+
| f_id           | int(15)     |
| f_client_id    | int(11)     |
| f_phone_type   | varchar(50) |
| f_phone_number | varchar(13) |
+----------------+-------------+

Таблица клиентов

+-----------------------------+--------------+------+-----+
| Field                       | Type         | Null | Key |
+-----------------------------+--------------+------+-----+
| f_id                        | int(15)      | NO   | PRI |
| f_first_name                | varchar(13)  | YES  | MUL |
| f_mi                        | char(1)      | YES  |     |
| f_last_name                 | varchar(20)  | NO   | MUL |
+-----------------------------+--------------+------+-----+

Предположения:

  1. Каждая запись в «Таблице телефонов» принадлежит одной записи в «Таблице клиентов».
  2. Каждая запись в «Таблице клиентов» может содержать 0 или более записей в «Таблице телефонов».
  3. Простой перевод: клиент может иметь 0 или более телефонных номеров

При стандартном соединении LEFT или INNER я получаю что-то вроде этого:

+------------+------------+--------------+
| name       | Phone Type | Phone Number |
+------------+------------+--------------+
| John Smith | Home       | 712-555-6987 |
| John Smith | Work       | 712-555-1236 |
+------------+------------+--------------+

Мне нужен запрос, который даст мне рабочие и домашние номера, которые принадлежат данному клиенту:

+------------+----------------+--------------+
| Name       | Work Number    | Home Number  |  
+------------+----------------+--------------+
| John Smith | 712-555-1236   | 712-555-6987 |
+------------+----------------+--------------+

Можно ли выполнить ЛЕВОЕ или ВНУТРЕННЕЕ объединение, а затем объединить эти результаты в одну строку? Я видел похожие вопросы по этому вопросу, но приведенные примеры были гораздо более сложными, чем то, что я делаю:

Подобные вопросы

Спасибо

Ответы [ 3 ]

1 голос
/ 02 апреля 2010

Хотя вы можете объединить несколько чисел (в любом) в одно поле:

SELECT
  CONCAT(f_first_name, ' ', f_last_name) as Client_Name,
  GROUP_CONCAT(IF(phone_type='work',f_phone_number, NULL)) as Work_Numbers,
  GROUP_CONCAT(IF(phone_type='home',f_phone_number, NULL)) as Home_Numbers
FROM clients
JOIN phone
  USING (f_id)
WHERE phone_type IN ('home', 'work')
GROUP BY f_id;
0 голосов
/ 02 апреля 2010

Существуют ли ограничения на количество рабочих или домашних номеров, которое может иметь конкретная запись клиента? Если их может быть много, то нет, нет способа сделать один ряд. Если их может быть не более 1, вы можете просто присоединиться к таблице телефонных номеров дважды.

0 голосов
/ 02 апреля 2010
SELECT CONCAT(c.f_first_name, ' ', c.f_last_name) as Client_Name, 
       wp.f_phone_number as Work_Number,
       hp.f_phone_number as Home_Number

  FROM clients c
       LEFT OUTER JOIN phone hp
       ON hp.f_client_id = c.f_id
    AND
       hp.phone_type = 'home'
       LEFT OUTER JOIN phone wp
       ON wp.f_client_id = c.f_id
    AND
       wp.phone_type = 'work'

С LEFT OUTER JOINs вы все равно получите строки для клиентов с пропущенными номерами.Если вы не хотите их видеть, измените на ВНУТРЕННИЕ СОЕДИНЕНИЯ.

Редактировать: Как любезно напоминает мне Ник, это вернет несколько строк для клиентов с несколькими номерами телефонов.Когда у вас есть необходимые данные, вы сталкиваетесь с проблемой презентации.Вы можете справиться с этим на прикладном уровне или принести жертву богам SQL и заглянуть в функцию MySQL GROUP_CONCAT ().

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