2010-11-01 4 views
4

У меня есть запрос, как это:SQL Алиас соединяемых таблиц

select a1.name, b1.info 
from (select name, id, status 
     from table1 a) as a1 
right outer join (select id, info 
        from table2 b) as b1 on (a1.id = b1.id) 

Я только хочу, чтобы включить все, где a1.status = 1 и, поскольку я использую внешнее соединение, я не могу просто добавить a where ограничение на таблицу1, потому что вся информация из таблицы2, которую я хочу исключить, по-прежнему будет присутствовать, просто без имени. Я думал примерно следующее:

select z1.name, z1.info 
    from ((select name, id, status 
      from table1 a) as a1 
right outer join (select id, info 
        from table2 b) as b1 on (a1.id = b1.id)) as z1 
    where z1.status = 1 

но я не думаю, что это законно.

EDIT: Как описано ниже, внешнее соединение фактически не имеет смысла для того, что я пытаюсь сделать. Что делать, если, например, я хочу, чтобы все данные из таблицы2, где status! = 1 в таблице1, включая все данные, где соответствующий идентификатор вообще не существует в таблице 1. Таким образом, мне понадобится внешнее объединение всех данных из таблицы2, но все же вы хотите исключить те записи, где status = 1.

Эквивалент это:

select z1.name, z1.info 
    from ((select name, id, status 
      from table1 a) as a1 
right outer join (select id, info 
        from table2 b) as b1 on (a1.id = b1.id)) as z1 
    where z1.status != 1 
+0

Я думаю, что понял свою проблему ... внешнее соединение не имеет смысла для того, что я делаю. Если статус должен быть 1, это значит, что запись должна существовать в таблице1, поэтому я должен использовать внутреннее соединение. – Lincecum

+0

@ Lincecum - В ответ на некоторые ваши комментарии - я не думаю, что вы понимаете, как работает 'JOIN'. «LEFT OUTER JOIN» показывает все записи в вашей первой таблице, а затем любые совпадающие записи со второго (или «NULL», если нет совпадения). «ПРАВИЛЬНАЯ ВСТРОЕННАЯ РАБОТА» делает обратное - все записи из таблицы 2, соответствующие только в таблице 1. «INNER JOIN» показывает вам только там, где критерии соответствуют/записи существуют в BOTH таблицах. – JNK

+0

На самом деле, я хорошо понимаю, что делает Join. Сначала я извлекал все данные из таблицы2, используя правое внешнее соединение, чтобы убедиться, что я получил все эти данные независимо от того, существует ли соответствующий идентификатор в таблице1. С тех пор я решил, что мне нужны только данные от тех, кто был активен, что указано в статусе таблицы1. Я пытался сделать эту модификацию, не понимая, что внешнее объединение становится бессмысленным, если соответствующая запись с активным статусом ДОЛЖНА существовать в таблице1. – Lincecum

ответ

2

Добавить статью where в subquery, как это:

select a1.name, b1.info from 
(
    select name, id 
    from table1 a 
    where a.status = 1 
) as a1 

right outer join 

(
    select id, info 
    from table2 b 
) as b1 on (a1.id=b1.id) 
0
select a1.name, b1.info from 
(select name, id, status from table1 a WHERE status=1) as a1 
right outer join 
(select id, info from table2 b) as b1 on (a1.id=b1.id) 

EDIT:

Для вашего второго сценария:

select a1.name, b1.info from 
(select name, id, status from table1 a) as a1 
right outer join 
(select id, info from table2 b) as b1 on (a1.id=b1.id) 
EXCEPT 
select a1.name, b1.info from 
(select name, id, status from table1 a WHERE status<>1) as a1 
right outer join 
(select id, info from table2 b) as b1 on (a1.id=b1.id) 

Это должно сработать, так как вы получите все данные таблицы2 независимо.

EDIT 2:

OK, чтобы получить все от table2 КРОМЕ где есть статус ID в таблице 1, даже если нет записи в table1, вам нужно использовать функцию EXCEPT, которая будет в основном исключить подмножество из большего набора данных.

+0

См. Выше. Поскольку это внешнее соединение, это не сработает. На самом деле это не исключает, что все вещи вытащили из таблицы2. – Lincecum

+0

Есть ли еще одна причина, по которой вам нужно сделать «ПРАВИЛЬНУЮ ВЗАИМУЮ РАБОТУ» на этом вместо левого или внутреннего? В большинстве случаев «ПРАВИЛЬНОЕ ПРИСОЕДИНЕНИЕ» почти никогда не требуется. – JNK

+0

Не совсем, пока это внешнее соединение. – Lincecum

10
SELECT a1.Name, b1.Info 
FROM table2 b1 
    JOIN table2 a1 ON b1.id= a1.id AND a1.status = 1 

Правое внешнее соединение делает то же самое, что и левое внешнее соединение, только с перестановкой таблиц. Вы можете фильтровать соединение, и оно будет содержать данные из начальной таблицы.

+0

Это действительно хороший пример. –