SAP HANA условное левое внешнее соединение - PullRequest
0 голосов
/ 20 марта 2019

У меня есть четыре разных таблицы:

TABLE_A
   field_1
   field_2
   field_3

TABLE_B
   field_4
   field_5
   field_6

TABLE_C
   field_7
   field_8

TABLE_D
   field_9
   field_10
   field_11

Я присоединяюсь к трем из них примерно так:

SELECT a."field_1"
     , a."field_2"
     , a."field_3"
     , c."field_7"
     , c."field_8"
FROM 
           TABLE_A a
INNER JOIN TABLE_B b
        ON b."field_4" = a."field_1"
LEFT OUTER JOIN TABLE_C c
        ON c."field_7" = b."field_5"
WHERE 
     a."field_1" IN (list of values)

Я хочу добавить условное JOIN к TABLE_D, чтобы получить значения "field_9" и "field_11".

Если b."field_6" не пусто, то должно быть левое внешнее соединение с TABLE_D на d."field_9" = b."field_6".

В противном случае должно быть левое внешнее соединение с уникальной записью в TABLE_D, где d."field_10" = b."field_4" and d."field_11" = 1.

Я не уверен, что это может быть достигнуто с помощью CASE ... какие-нибудь идеи есть?

Спасибо

1 Ответ

0 голосов
/ 21 марта 2019

Правильный термин для того, что вы ищете, это «условное соединение». В SAP HANA термин «динамическое соединение» используется совсем по-другому.

Я соответственно отредактировал ваш вопрос и добавил немного форматирования.

Чего не хватает в вашем вопросе - это минимальный пример для работы. Это будет включать CREATE TABLE операторы для таблиц и INSERT команды для данных.

Без них всем предстоит гораздо больше проработать ваши требования и посмотреть, правильно ли работает решение.

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

select current_timestamp, * from m_database;
/*
CURRENT_TIMESTAMP       SYSTEM_ID   DATABASE_NAME   HOST    START_TIME              VERSION                 USAGE      
2019-03-21 01:05:19.827 HXE         HXE             hxehost 2019-03-21 00:18:01.659 2.00.035.00.1545187853  DEVELOPMENT
*/

create column table tab_a (f1 integer, f2 integer, f3 integer);
create column table tab_b (f4 integer, f5 integer, f6 integer);
create column table tab_c (f7 integer, f8 integer);
create column table tab_d (f9 integer, f10 integer, f11 integer);

-- A
insert into tab_a values (10, 12, 13);
insert into tab_a values (20, 22, 23);
insert into tab_a values (30, 22, 23);
insert into tab_a values (50, 52, 53);

select * from tab_a;
/*
F1  F2  F3
10  12  13
20  22  23
30  22  23
50  52  53
*/

-- B
insert into tab_b values (10, 120, 130);
insert into tab_b values (20, 220, 230);
insert into tab_b values (30, 230, 230);

insert into tab_b values (50, 500, NULL); // <- join case with f6 IS NULL

select * from tab_b;
/*
F4  F5  F6 
10  120 130
20  220 230
30  230 230
50  500 ?  
*/

-- C
insert into tab_c values (120, 1200);
insert into tab_c values (220, 2200);
insert into tab_c values (230, 2200);

select * from tab_c;

/*
F7  F8  
120 1200
220 2200
230 2200
*/

-- D
insert into tab_d values (3001, 50, 1);
insert into tab_d values (20, 2200, 999 );
insert into tab_d values (30, 2200, 999 );

insert into tab_d values (230, 2200, 999 );
insert into tab_d values (130, 1200, 999 );

select * from tab_d;
/*
F9      F10     F11
3001    50      1  
20      2200    999
30      2200    999
230     2200    999
130     1200    999
*/ 


-- orig
SELECT a.f1
     , a.f2
     , a.f3
     , c.f7
     , c.f8
FROM 
           tab_a a
INNER JOIN tab_b b
        ON b.f4 = a.f1
LEFT OUTER JOIN tab_c c
        ON c.f7 = b.f5
WHERE 
     a.f1 IN (10, 20, 30, 50);

/*
F1  F2  F3  F7  F8  
10  12  13  120 1200
20  22  23  220 2200
30  22  23  230 2200
50  52  53  ?   ?   
*/

До этого момента код просто воспроизводит ваш пример и опубликованный вами SQL. Обратите внимание, как «особый» случай с "f1" = 50 отличается от NULLs in F7 и F8.

Теперь, хотя SAP HANA поддерживает функцию, называемую "case" -соединение (которая может использоваться для условного объединения разных таблиц), прямой подход для вашего требования - выполнить два OUTER JOIN.

Это хорошо работает, поскольку ваше состояние приводит к двум взаимоисключающим случаям: TABLE_B."f6" НЕДЕЙСТВИТЕЛЕН или нет.

Чтобы отобразить два набора результирующих столбцов в один набор в проекции, мы можем использовать функции COALESCE или IFNULL, чтобы получить правильный набор столбцов.

-- new
SELECT a.f1
     , a.f2
     , a.f3
     , c.f7
     , c.f8   
     , coalesce(d1.f9, d2.f9)  f9_cond
     , coalesce(d1.f11, d2.f11) f11_cond 

FROM 
           tab_a a
INNER JOIN tab_b b
        ON b.f4 = a.f1

LEFT OUTER JOIN tab_c c
        ON c.f7 = b.f5

LEFT OUTER JOIN tab_d d1
        ON   b.f6 IS NOT NULL 
        AND  b.f6 = d1.f9

LEFT OUTER JOIN tab_d d2
        ON   b.f6 IS NULL 
        AND  d2.f11 = 1
        AND  b.f4 = d2.f10

WHERE 
     a.f1 IN (10, 20, 30, 50);  

/*
F1  F2  F3  F7  F8      F9_COND F11_COND
10  12  13  120 1200    130     999     
20  22  23  220 2200    230     999     
30  22  23  230 2200    230     999     
50  52  53  ?   ?       3001    1       
*/

Обратите внимание, что это стандартный SQL, и он не связан с работой SAP HANA. Быстрый поиск с правильным термином «условное объединение» дал бы множество результатов для этого.

...