2015-02-03 9 views
0

Я пытаюсь создать единый оператор выбора из двух отдельных.SQL SELECT from SELECT

В принципе у меня есть список имен в таблице, которые действительно повторяются, как так:

Name| Date 
John 2014-11-22 
John 2013-02-03 
Joe 2012-12-12 
Jack 2011-11-11 
Bob 2010-10-01 
Bob 2013-12-22 

Мне нужно сделать Select distinct Name from Records, который возвращает Джон, Джо, Джек, Боб.

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

SELECT Address, Phone From dbo.Details 
WHERE Name = {Values from first SELECT query} 

Возникли проблемы с синтаксисом.

+2

MySQL или SQL Server? Или оба? –

+1

Я удалил тег 'mysql', поскольку таблицы ссылаются на два имени, а' dbo.' - схема по умолчанию в SQL Server. @sd_dracula: В следующий раз, пожалуйста, перейдите к своим тегам, прежде чем отправлять вопрос. Благодарю. – Pred

ответ

4

Если вы не хотите, чтобы вернуть все значения из подзапроса, вы можете использовать либо IN или EXISTS

SELECT Address, Phone From dbo.Details 
WHERE Name IN (SELECT DISTINCT Name FROM Records) 

-- OR -- 

SELECT Address, Phone From dbo.Details D 
WHERE EXISTS (SELECT 1 FROM Records R WHERE R.Name = D.Name) 

(В большинстве RDBMS СУЩЕСТВУЕТ меньше ресурсов интенсивный).

Если вы хотите, чтобы возвращать значения из подзапроса, вы должны использовать JOIN

SELECT 
    D.Address, 
    D.Phone, 
    R.Name -- For example 
FROM 
    dbo.Details D 
    INNER JOIN dbo.Records R 
    ON D.Name = R.Name 

Sidenote Эти примеры запросов, то возможно, что вы должны точно настроить их, чтобы соответствовать вашим требованиям.

+0

, используя IN, конечно. не мог думать об этом. Спасибо, вот что я искал. –

+0

Добро пожаловать, но я рекомендую использовать 'EXISTS' вместо' IN'. Пожалуйста, дважды проверьте мой комментарий после этой части;) – Pred

0

Это даст вам имена и их адрес и номер телефона:

SELECT DISTINCT N.Name, D.Address, D.Phone 
FROM dbo.Details D INNER JOIN dbo.Names N ON D.Name = N.Name 
+0

Простите, отправил в спешке, прежде чем я закончил –

+0

Это все еще не то, что хочет OP. Это приведет к возврату нескольких значений, если таблица имен имеет более одного имени. Скажем, в таблице «Подробности» есть «Крис», и есть 3 строки в именах с «Крисом». –

+0

На самом деле это не так. Если бы было несколько строк адреса/номера телефона, вы получили бы только дубликаты. –

1

Вы можете использовать:

SELECT Address, Phone, name 
FROM details 
-- "in" is the difference from your first query, needed due to multiple values being returned by the subquery 
WHERE name in ( 
    SELECT distinct name 
    FROM namesTable 
) 

Дополнительно должно работать:

SELECT d.Address, d.Phone, n.name 
FROM details d 
inner join (
    select distinct name 
    from namesTable 
) n on d.name = n.name 
+0

Я бы порекомендовал EXISTS вместо IN (например, http://stackoverflow.com/questions/2065329/sql-server-in-vs-exists-performance) и, безусловно, над IN (SELECT DISTINCT). Но в остальном я согласен с вашим ответом ... Мой в основном тот же :-) – evanv

0

При использовании подзапрос, который не является скалярным (не возвращает только одно значение) в разделе where использует IN и, конечно, только один colu mn в подзапросе:

SELECT Address, Phone 
From dbo.Details 
WHERE Name IN (Select Name from Table) 
+2

Я бы порекомендовал EXISTS для такого рода вещей, например http://stackoverflow.com/questions/2065329/sql-server-in-vs -exists-performance, но в остальном это очень эффективный способ приблизиться к нему – evanv

1

Таким образом, вы можете сделать это двумя способами. Во-первых, создайте временную таблицу и выполните соединение (* на самом деле ретроспективно вы также можете присоединиться ко второй таблице в качестве подзапроса или использовать что-то вроде CTE, если вы используете SQL SERVER, но изменения, если вы хотите пойти маршрут должен быть довольно очевидно)

CREATE TEMPORARY TABLE my_table AS 
{your first select query}; 

SELECT Address, Phone From dbo.Details 
INNER JOIN my_table AS mt 
ON mt.name = dbo.name 

Другим вариантом было бы выполнить IN или EXISTS запрос, используя ваш выбор запроса

SELECT Address, Phone From dbo.Details 
WHERE name IN (SELECT name from my_table) 

или еще лучше (например, SQL Server IN vs. EXISTS Performance),

SELECT Address, Phone From dbo.Details 
    WHERE EXISTS (SELECT * from my_table WHERE my_table.name = dbo.name) 

Возможно, вам придется немного изменить синтаксис, в зависимости от того, используете ли вы MySQL или SQL Server (не уверен в этом позже, честно). Но это должно вам начать вниз правильный путь