2012-01-18 4 views
3

Мне нужно добавить условие значения к ПОЛНОЙ ВНЕШНИМ СОЕДИНЕНИЕМ.FULL OUTER JOIN условие состояния

I.e. Я triyng сделать это:

SELECT * 
FROM Table1 
FULL OUTER JOIN Table2 ON Table1.Field1 = Table2.Field1 AND Table2.Field2 > 5 

Но этот сценарий не работает. На самом деле это выглядит как условие (Table2.Field2> 5) никогда не применялось вообще.

Эта же проблема возникает для ПРАВИЛЬНОЙ ВСТРОЕННОЙ ВСТУПЛЕНИЯ, поэтому я думаю, что причина в том, что когда есть ПРАВО или ПОЛНОСТЬЮ, не присоединяются никакие условия значения, применяемые к правой таблице в соединении.
Почему это происходит? Существует ли концептуальное объяснение такого поведения?

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

Есть ли способ решить эту проблему без использования подзапросов?

SELECT * 
FROM Table1 
FULL OUTER JOIN (SELECT * FROM Table2 WHERE Table2.Field2 > 5) AS t2 ON Table1.Field1 = t2.Field1 

ответ

1

Довольно convulated но не подзапросов

SELECT Table1.* 
     , CASE WHEN Table2.Field2 > 5 THEN Table2.Field1 ELSE NULL END 
     , CASE WHEN Table2.Field2 > 5 THEN Table2.Field2 ELSE NULL END   
FROM Table1 
     FULL OUTER JOIN Table2 ON Table1.Field1 = Table2.Field1 
WHERE COALESCE(Table2.Field2, 6) > 5 
     OR Table1.Field1 = Table2.Field1 

тестовый скрипт

;WITH Table1 AS (
    SELECT * FROM (VALUES 
    (1, 1) 
    , (2, 2) 
    , (5, 5) 
    , (6, 6) 
) AS Table1 (Field1, Field2) 
) 
, Table2 AS (
    SELECT * FROM (VALUES 
    (1, 1) 
    , (3, 3) 
    , (4, 4) 
    , (5, 5) 
    , (7, 7) 
) AS Table2 (Field1, Field2) 
) 
SELECT Table1.* 
     , CASE WHEN Table2.Field2 > 5 THEN Table2.Field1 ELSE NULL END 
     , CASE WHEN Table2.Field2 > 5 THEN Table2.Field2 ELSE NULL END   
FROM Table1 
     FULL OUTER JOIN Table2 ON Table1.Field1 = Table2.Field1 
WHERE COALESCE(Table2.Field2, 6) > 5 
     OR Table1.Field1 = Table2.Field1 

Результаты

Field1 Field2 Field1 Field2 
1  1  NULL NULL 
5  5  NULL NULL 
NULL NULL 7  7 
6  6  NULL NULL 
1  1  NULL NULL 
2  2  NULL NULL 
+0

Спасибо, но это еще не решение, которое я искал.Хотя этот подход сохраняет структуру запросов (критически для меня, потому что оператор SQL генерируется автоматически), поэтому это еще более подходящее решение, чем предыдущее. Еще много дополнительного кода, поэтому, возможно, мне пришлось реализовать подзапрос в конце. Но это решение достаточно хорошо, поэтому я думаю, что могу принять его в качестве ответа. – SergeyT

3

То, что вы хотите, можно было бы сформулировать так:

SELECT * 
    FROM Table1 
    LEFT JOIN Table2 ON Table1.Field1 = Table2.Field1 AND Table2.Field2 > 5 
    UNION ALL 
SELECT * 
    FROM Table1 
    RIGHT JOIN Table2 ON Table1.Field1 = Table2.Field1 
    WHERE Table2.Field2 > 5 
    AND Table1.Field1 IS NULL 

, но с использованием подзапроса как предложено самостоятельно ИМО лучший вариант.

+0

Спасибо за предложение, но это не очень хорошее решение для меня. Это сработает, вы правы, но это еще сложнее, чем простой подзапрос. – SergeyT

+2

@SergeyT: Вы спрашивали без подзапросов, я отвечаю без подзапросов. Вероятно, ваше решение - лучший вариант. В зависимости от СУБД вы можете включить его в предложение WITH. – Benoit

0

Это меня путают. Теперь я понимаю! Условия после «on» (в вашем случае: Table1.Field1 = Table2.Field1 AND Table2.Field2> 5) сообщает оператору объединения, к которому привязаны строки из двух таблиц. Это означает, когда и только тогда, когда row1 из table1 и row2 из таблиц удовлетворяют как row1.field1 = row2.field2, так и row2.field2> 5, что row1 и row2 объединены. Остальные строки не объединены.

Таким образом, при полном внешнем соединении результирующий набор затем будет соединен рядами, несвязанными строками из таблицы 1 и несвязанными рядами из таблицы2. В правом соединении результирующий набор будет соединен рядами, несвязанными строками из таблицы2. В любом случае строки из таблицы 2 с полем 2 < = 5 будут среди наборов результатов несвязанных строк из таблицы2.

Именно поэтому «Table2.Field2> 5» работает правильно в левом соединении, но не «правильно» в правом или полном соединении, но условия значения действительно выполняют свои задания правильно.

 Смежные вопросы

  • Нет связанных вопросов^_^