SAP HANA 条件左外连接
SAP HANA conditional left outer join
我有四个不同的表:
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)
我想向 TABLE_D
添加条件 JOIN 以获得 "field_9"
和 "field_11"
的值。
如果 b."field_6"
不为空,则 d."field_9" = b."field_6"
上应该有一个带 TABLE_D
的 LEFT OUTER JOIN。
否则应该有一个 LEFT OUTER JOIN 到 TABLE_D
中的 UNIQUE 条目,其中 d."field_10" = b."field_4" and d."field_11" = 1
.
我不确定这是否可以通过 CASE 实现...有什么想法吗?
谢谢
您要查找的内容的正确术语是 "conditional join"。在 SAP HANA 中,术语 "dynamic join" 的用法非常不同。
我相应地编辑了你的问题并添加了一些格式。
你的问题中缺少的是一个最小的例子。这将包括表的 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
的 "special" 案例如何与 F7
和 F8
.
中的 NULLs
脱颖而出
现在,虽然 SAP HANA 支持称为 "case"-join 的功能(可用于有条件地连接到不同的表),但满足您要求的直接方法是执行两个 OUTER JOIN
.
这很有效,因为您的条件会导致两种互斥的情况:TABLE_B."f6"
IS NULL 或不是。
要将两组结果列映射到投影中的一组,我们可以使用 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 的工作方式无关。使用正确的术语 "conditional join" 进行快速搜索会为此提供大量结果。
我有四个不同的表:
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)
我想向 TABLE_D
添加条件 JOIN 以获得 "field_9"
和 "field_11"
的值。
如果 b."field_6"
不为空,则 d."field_9" = b."field_6"
上应该有一个带 TABLE_D
的 LEFT OUTER JOIN。
否则应该有一个 LEFT OUTER JOIN 到 TABLE_D
中的 UNIQUE 条目,其中 d."field_10" = b."field_4" and d."field_11" = 1
.
我不确定这是否可以通过 CASE 实现...有什么想法吗?
谢谢
您要查找的内容的正确术语是 "conditional join"。在 SAP HANA 中,术语 "dynamic join" 的用法非常不同。
我相应地编辑了你的问题并添加了一些格式。
你的问题中缺少的是一个最小的例子。这将包括表的 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
的 "special" 案例如何与 F7
和 F8
.
NULLs
脱颖而出
现在,虽然 SAP HANA 支持称为 "case"-join 的功能(可用于有条件地连接到不同的表),但满足您要求的直接方法是执行两个 OUTER JOIN
.
这很有效,因为您的条件会导致两种互斥的情况:TABLE_B."f6"
IS NULL 或不是。
要将两组结果列映射到投影中的一组,我们可以使用 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 的工作方式无关。使用正确的术语 "conditional join" 进行快速搜索会为此提供大量结果。