Соединить одну строку с несколькими строками в другой таблице - PullRequest
19 голосов
/ 23 мая 2010

У меня есть таблица с сущностями (давайте назовем их людьми) и свойствами (один человек может иметь произвольное количество свойств). Пример:

Люди

Name  Age
--------
Jane  27
Joe   36
Jim   16

Свойства

Name   Property
-----------------
Jane   Smart
Jane   Funny
Jane   Good-looking
Joe    Smart
Joe    Workaholic
Jim    Funny
Jim    Young

Я хотел бы написать эффективный выбор, который бы выбирал людей по возрасту и возвращал все или некоторые из их свойств.

Ex: People older than 26
Name Properties
Jane Smart, Funny, Good-looking
Joe Smart, Workaholic

Также допустимо возвращать одно из свойств и общее количество свойств.

Запрос должен быть эффективным: миллионы строк в таблице пользователей, сотни тысяч строк в таблице свойств (поэтому у большинства людей нет свойств). За один раз выбираются сотни строк.

Есть ли способ сделать это?

Ответы [ 3 ]

23 голосов
/ 23 мая 2010

Использование:

   SELECT x.name,
          GROUP_CONCAT(y.property SEPARATOR ', ')
     FROM PEOPLE x
LEFT JOIN PROPERTIES y ON y.name = x.name
    WHERE x.age > 26
 GROUP BY x.name

Требуется функция MySQL GROUP_CONCAT ( документация ) для возврата списка значений PROPERTIES.property через запятую.

Я использовал LEFT JOIN, а не JOIN, чтобы включить записи PEOPLE, которые не имеют значения, в таблицу PROPERTIES - если вам нужен только список людей со значениями в таблице PROPERTIES, используйте:

   SELECT x.name,
          GROUP_CONCAT(y.property SEPARATOR ', ')
     FROM PEOPLE x
     JOIN PROPERTIES y ON y.name = x.name
    WHERE x.age > 26
 GROUP BY x.name

Я понимаю, что это пример, но использование имени - плохой выбор для ссылочной целостности, если учесть, сколько существует "Джона Смита". Назначение user_id в виде числового значения было бы лучшим выбором.

4 голосов
/ 05 мая 2015
SELECT x.name,(select GROUP_CONCAT(y.Properties SEPARATOR ', ')
FROM PROPERTIES y 
WHERE y.name.=x.name ) as Properties FROM mst_People x 

попробуйте это

3 голосов
/ 23 мая 2010

Вы можете использовать INNER JOIN, чтобы связать две таблицы вместе. Больше информации о СОЕДИНЕНИЯХ .

SELECT *
FROM People P
INNER JOIN Properties Pr
  ON Pr.Name = P.Name
WHERE P.Name = 'Joe' -- or a specific age, etc

Однако часто гораздо быстрее добавить уникальный первичный ключ к таким таблицам и создать index для увеличения скорости.

Скажем, в таблице People есть поле id
И таблица Properties имеет поле peopleId, чтобы связать их вместе

Тогда запрос будет выглядеть примерно так:

SELECT *
FROM People P
INNER JOIN Properties Pr
  ON Pr.id = P.peopleId
WHERE P.Name = 'Joe'
...