2016-05-03 2 views
1

В настоящее время у меня сложный SQL-запрос, который вставляется в временную таблицу. Запрос включает в себя OUTER APPLY, поскольку не все возвращенные записи будут применяться к набору результатов.Отфильтровать столбец OUTER APPLY в разделе WHERE

Мне также необходимо использовать столбцы OUTER APPLY в предложении WHERE для фильтрации результатов, но также включать результаты, которые не относятся к OUTER APPLY .e. Все результаты Outer APPLY = 1 и не внешние результаты.

Это простая версия макета запроса:

INSERT INTO #temp (X, Y, Z, O1, O2) 
SELECT 
    X Y Z 
FROM T1 
INNER JOIN T2, T etc. 
OUTER APPLY (
    SELECT O1, O2 FROM XYZ…) OATable 
WHERE 
    OATable.O1 = 1 -- I tried just adding “IN (1, NULL)” but this 
still excludes the results. 

Любая помощь будет принята с благодарностью.

Платформа: SQL Server 2012+

Спасибо

+0

Я заинтригован фактического запроса; ответы пока кажутся хорошими, но я не думаю, что мы (потенциальные ответчики) действительно можем судить, если мы будем отвечать на основе вашего очень упрощенного запроса. Если вы можете отправить полный запрос, пожалуйста, можете ли вы это сделать? Это может помочь получить более совершенный ответ. –

+0

Некоторые примеры данных также были бы полезными, возможно. –

ответ

3

Вы не можете сравнивать непосредственно NULL, потому что ничего не приравнивает к NULL (даже не сам NULL). Это исключает использование здесь IN. Вместо этого, просто использовать OR заявление:

INSERT INTO #temp (X, Y, Z, O1, O2) 
SELECT 
    X, Y, Z, 
FROM T1 
INNER JOIN T2 ON ... 
OUTER APPLY (SELECT O1, O2 FROM XYZ…) OATable 
WHERE 
    OATable.O1 = 1 OR OATable.O1 IS NULL 

Это предполагает, что O1 является NOT NULL столбец в XYZ.

+0

Вы проверили это? Я сделал. Если 01 не является нулевым, то OATable.O1 IS NULL всегда будет ложным. Даже если значение 01 является нулевым, оно все равно будет находить только фактические значения null. Это не относится также к результатам, которые не применяются к ВНЕШНЕМУ ПРИМЕНЕНИЮ. – Paparazzi

0

Я думаю, что ответ от Тома H адресов заявленного вопроса
Но я думаю, что это может быть то, что вы на самом деле ищете

SELECT X Y Z, OATable.* 
FROM T1 
INNER JOIN T2, T etc. 
LEFT JOIN XYZ as OATable 
     on OATable.O1 = 1 

В ответе от Тома вам нужно будет буквальный OATable.O1 IS NULL (из моих выводов)
И это не произойдет, если столбец определен как NOT NULL
OATable.O1 IS NULL в наружном будет применяться только найти буквальное значение NULL, даже если столбец допускает нулевой

В ответ вы получите левую сторону, не матч на OATable O1 = 1

+0

Я согласен с вашим инстинктом в том, что ВНЕШНИЕ ПРИМЕНЕНИЯ вряд ли будут правильным подходом, но я не уверен в вашем оправдании почему. Я думаю, что ответ @ TomH, вероятно, сработает, и вы можете быть недопониманием OUTER APPLY. (не уверен, хотя!) –

+0

@StuartJCuthbertson then test - я сделал – Paparazzi

+0

Я определенно обеспокоен состоянием вашего LEFT JOIN, которое соответствует константе, поэтому будет соответствовать всем строкам левой стороны. Это кажется маловероятным, я думаю, что может существовать условие объединения, скрытое в реальном запросе OP, что мы еще не были показаны. –

0

Является ли это то, что вы пытаетесь достичь:

CREATE TABLE #T1 (X INT, y INT, z INT); 
INSERT INTO #T1 
     (X, y, z) 
VALUES (1 -- X - int 
      , 2 -- y - int 
      , 3 -- z - int 
      ); 
CREATE TABLE #t2 (a INT, b INT); 
INSERT INTO #t2 
     (a, b) 
VALUES (2 -- a - int 
      , 5 -- b - int 
      ); 
CREATE TABLE #xyz (a1 INT, a2 INT); 
INSERT INTO #xyz 
     (a1, a2) 
VALUES (1 -- a1 - int 
      , 20 -- a2 - int 
      ), 
     (NULL, 30); 

SELECT Insertdata.X 
     , Insertdata.y 
     , Insertdata.z 
     , Insertdata.a 
     , Insertdata.b 
     , Insertdata.a1 
     , Insertdata.a2 
INTO #temp 
FROM (SELECT INQ.X 
        , INQ.y 
        , INQ.z 
        , INQ.a 
        , INQ.b 
        , O.a1 
        , O.a2 
      FROM  (SELECT X 
           , y 
           , z 
           , a 
           , b 
         FROM  #T1 
           INNER JOIN #t2 
           ON y = a 
        ) AS INQ 
        OUTER APPLY (SELECT a1 
              , a2 
            FROM  #xyz 
           ) AS O 
      WHERE  a1 = 1 
        OR a1 IS NULL 
     ) AS Insertdata; 

SELECT X 
     , y 
     , z 
     , a 
     , b 
     , a1 
     , a2 
FROM #temp; 
Смежные вопросы