Как выполнить запрос выбора MySQL для двух таблиц, связанных другой таблицей - PullRequest
4 голосов
/ 24 июля 2010

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

Предположим, у меня есть две таблицы: одна для имени человека и другая для телефонных номеров:

Table 1:
id   person's name
1    John
2    Smith

Table 2:
id   Phone number
5     23424224
6      23424242

А затем у меня есть третья таблица, которая связывает человека и соответствующие телефонные номера:

Table 3:
id    person-id    phone-number-id
1         1           5
2         2           6

Следовательно, у Джона есть телефонный номер 23424224, а у Смита есть телефонный номер 23424242.

И я хочу выполнить SQL-запрос, чтобы выбрать всех людей из Таблицы 1, чей номер телефона начинается, скажем, с (234).

Как бы я связал запросы на выборку в этой структуре таблицы ...какой запрос я бы запустил?

Ответы [ 6 ]

3 голосов
/ 24 июля 2010

Во-первых, единственная причина, по которой можно составить эту таблицу, - это если у вас есть отношение «многие ко многим». В то время как у человека может быть много телефонных номеров, может ли один телефонный номер иметь много людей? Если это так, то ваша схема реализует это требование, но мне кажется, что оно немного перегружено: -)

Во-вторых, это довольно простое соединение. Что вы хотите сделать, это сначала выбрать номера телефонов, о которых идет речь, затем с учетом этого выбрать идентификаторы лиц из третьей таблицы, а затем с учетом этого выбрать имена из первой таблицы. Что-то вроде:

ВЫБРАТЬ t1.name в качестве имени, t2.number из таблицы1 t1, table2 t2, table3 t3, где t2.number, например, «234%» и t3.personid = t1.id и t3.phoneid = t2.id;

Вы также можете переписать "blah.id = blah.id" как объединение, если вам нужна семантика внешнего объединения (включая определенные поля с NULL).

0 голосов
/ 24 июля 2010

Во-первых ... вам не нужен столбец id in Table 3.

Просто сделайте personId и phoneId как первичный ключ .

Это цель вашей таблицы «многие ко многим» (связать несколько телефонов с одним человеком).Вы можете иметь один и тот же идентификатор человека для разных идентификаторов телефонов и наоборот, то есть вы можете иметь один и тот же идентификатор телефона для разных идентификаторов людей.У вас никогда не будет двух строк с одинаковым идентификатором человека и идентификатором телефона.Это не имеет никакого смысла.

С помощью этого запроса вы получите ожидаемый результат:

SELECT p.*
FROM Person as p, Phone as ph, PersonPhone as pf
WHERE pf.PersonId = p.Id AND pf.PhoneId = ph.Id and ph.Number like '234%'
0 голосов
/ 24 июля 2010

Это было бы что-то вроде следующего.Используя стандартный SQL, здесь мы используем внутреннее соединение с таблицей лиц, чтобы получить имя, а затем другое соединение с результирующим подзапросом (фильтрация по шаблону вашего телефона), чтобы получить людей, которые соответствуют номерам.

0 голосов
/ 24 июля 2010

выберите person.id, person.name из
table1 в качестве лица,
table2 в виде чисел,
table3 в качестве ссылки
где person.id = link.person-id
и numbers.id = link.phone-number-id
и numbers.phonenumber, например, '234%'

0 голосов
/ 24 июля 2010

Для номеров на человека:

SELECT persons.name, numbers.phone_number FROM persons
  LEFT JOIN person_number ON person_number.person-id = persons.id
  LEFT JOIN numbers ON person_number.phone-number-id = numbers.id

Для лиц на номер

SELECT persons.name, numbers.phone_number FROM numbers
  LEFT JOIN person_number ON person_number.phone-number-id = numbers.id
  LEFT JOIN persons ON person_number.person-id = persons.id
0 голосов
/ 24 июля 2010

Я принял имена столбцов для имени и номера телефона человека и предположил, что вы хотите вернуть список людей, у которых любой номер телефона начинается с 234 (вместо этого должны начинаться все его номера телефона) 234).

SELECT 
    persons-name
FROM
    Table1
WHERE
    id IN
        (SELECT
             Table3.person-id
         FROM
             Table3
             INNER JOIN Table2 ON Table2.id = Table3.phone-number-id
         WHERE
             phone-number like '234%')

Я должен признать, что знаю только MS-SQL, поэтому потенциально я добавлю некоторые специфичные для платформы функции, дайте мне знать, если у вас возникнут проблемы.

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

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