Какие есть варианты для вложенной структуры case-типа в объединении таблиц в TSQL? - PullRequest
0 голосов
/ 11 апреля 2019

Мне нужно объединение при двух условиях - первое простое, но второе, похоже, требует вложенного оператора case, но я не смог выяснить, как заставить его работать или какой-то лучший вариант.

Проблема в том, что у меня есть активность, которая может происходить один или два раза в день.Если это происходит один раз в день, я могу просто присоединиться к дате.Если это происходит два раза в день, мне нужно соответствующим образом объединить таблицу X в таблицу Y, в зависимости от того, будет ли это утро или после полудня, и при этом мне нужно в основном округлять множество раз с утра и после обеда до единого значения для каждого дляприсоединиться.

Это прекрасно работает:

Inner join table x on x.ser = y.ser and (case when X <= 12 then 9 else 
15) = (case when Y <= 12 then 9 else 15)

Но если я добавлю еще один оператор case вокруг оригинала, он развалится и все равно будет выглядеть как дерьмовый код, так что я думаю, что должен быть лучший способ решить эту проблемуно это ускользает от меня

case when (code = BID) then 
(case when X <= 12 then 9 else 15) = (case when Y <= 12 then 9 else 15)
else X = Y

Фактический нерабочий код указан ниже.

    INNER JOIN dbo.Image img on img.Ser = sa.Ser and 
        case when (ac.ActivityCode = 'BID') then    
            CASE WHEN DATEPART(hour, img.CreationDate) <= 12 THEN 
                 DATEADD(hh, 9, DATEADD(dd, DATEDIFF(dd, 0, 
                 img.CreationDate), 0)) ELSE DATEADD(hh, 15, DATEADD(dd, 
                 DATEDIFF(dd, 0, img.CreationDate), 0))  
            END = CASE WHEN DATEPART(hour, sa.ActualStartDate) <= 12 THEN 
                       DATEADD(hh, 9, DATEADD(dd, DATEDIFF(dd, 0, 
                        sa.ActualStartDate), 0)) ELSE DATEADD(hh, 15, 
                        DATEADD(dd, DATEDIFF(dd, 0, sa.ActualStartDate), 
                        0)) 
                    END 
          ELSE  sa.ActualStartDate = img.CreationDate
        END

1 Ответ

0 голосов
/ 11 апреля 2019

Вы не можете иметь оператор сравнения {expression 1} = {expression 2} внутри оператора CASE.

Это должно быть что-то вроде

INNER JOIN dbo.Image img  on  img.Ser = sa.Ser 
                         and  CASE ... END = CASE ... END

Но чем ваш запрос будет трудно прочитать. Почему бы не использовать CTE. И вычислить новое выражение внутри CTE

; WITH
CTE1 AS 
( 
    Col2 = CASE WHEN DATEPART(hour, img.CreationDate) <= 12 .....
),
CTE2 AS 
( 
    Col2 = CASE WHEN DATEPART(hour, sa.ActualStartDate) <= 12 .....
)
SELECT *
FROM   CTE1 c1 
JOIN   CTE2 c2  ON c1.Ser  = c2.Ser
               AND c2.Col2 = c2.Col2
...