Столбцы SQL SELECT из нескольких таблиц без повторяющихся данных - PullRequest
3 голосов
/ 30 ноября 2011

Я пытаюсь запросить 2 таблицы, используя следующую инструкцию sql, пытаясь вернуть все записи из каждой таблицы, содержащей конкретный идентификатор.

SELECT Phone.Phone, Email.Email FROM Contacts.Phone, Contacts.Email 
WHERE Phone.ContactId = :contactId AND Email.ContactId = :contactId

Contacts.Phone Таблица содержит 2 телефонных номера дляданный идентификатор и Contacts.Email содержит 1 электронное письмо для данного идентификатора.Используя приведенный выше SQL-запрос, я получаю следующие строки.Конечно, это всего лишь пример ситуации, когда мой набор результатов из каждой таблицы совпадает по количеству строк.

Row 1: 555-555-5555 - email@email.com
Row 2: 666-666-6666 - email@email.com

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

Row 1: 555-555-5555 - email@email.com
Row 2: 666-666-6666 - NULL

Я думаю, мне нужно использовать UNION, чтобы каким-то образом объединить таблицы, но я не могу понять, как именно написать оператор sql.Другой вариант - выполнить 2 отдельных запроса SQL, что было бы проще, но я считаю, что с точки зрения производительности лучше собрать все данные, которые мне нужны, в одном запросе.

Я использую MySQL.

Ответы [ 3 ]

2 голосов
/ 30 ноября 2011

Используйте left outer join для решения вашей проблемы, если бы вы использовали MS SQL, запрос выглядел бы так:

SELECT 
    Phone.Phone, 
    Email.Email 
FROM 
    Contacts.Phone 

Left Outer Join Contacts.Email ON Phone.ContactId = Email.ContactId

Ваши результаты будут выглядеть следующим образом:

Row 1: 555-555-5555 - email@email.com 
Row 2: 666-666-6666 - NULL 
1 голос
/ 30 ноября 2011

Прежде всего, я думаю, что это:

Другим вариантом было бы выполнить 2 отдельных запроса SQL, что было бы проще, но я считаю, что с точки зрения производительности было бы лучше собрать все необходимые мне данные в одном запросе.

немного ошибочно. Разница в производительности между одним сложным запросом и двумя простыми запросами будет довольно небольшой. Тем не менее, вы предложили использовать UNION; если вы хотите использовать один запрос, вы можете сделать это:

SELECT 'EMAIL', Email.Email
  FROM Contacts.Email
 WHERE Email.ContactId = :contactId
UNION ALL
SELECT 'PHONE', Phone.Phone
  FROM Contacts.Phone
 WHERE Phone.ContactId = :contactId
 ORDER BY 1 -- put e-mail addresses before phone-numbers
;

Первый столбец будет возвращать «тип» результата, а второй столбец будет иметь данные.

0 голосов
/ 30 ноября 2011

Если вы действительно хотите получить результаты в двух столбцах с NULL для повторяющихся данных, то было бы действительно полезно, если бы MySQL поддерживал синтаксис RANK() OVER (PARTITION BY ..., который допускают некоторые другие системы СУБД.К сожалению, это не так, но Даниэль Вассалло пришел на помощь, описав, как это можно сделать в MySQL в этом вопросе .

Адаптируя свой подход к вашей ситуации:

SELECT Phone.Phone,
    CASE Email.Email
    WHEN @curEmail THEN NULL
    ELSE @curEmail := Email.Email END AS Email
FROM Contacts.Phone, Contacts.Email, (SELECT @curEmail := '') AS r
WHERE Phone.ContactId = :contactId AND Email.ContactId = :contactId

Когда я запустил это на тестовых данных в вашем вопросе, я получил:

Row 1: 555-555-5555 - email@email.com
Row 2: 666-666-6666 - NULL

, который является желаемым результатом.

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