在比较不正确的地方跳过加入

时间:2019-08-13 20:52:24

标签: sql oracle join case where-clause

我正在尝试在两个表上执行左联接。通过我要加入的比较之一,该比较仅适用于某些值。当我们查看这些特定值时,SQL中是否可以执行比较,否则跳过该比较?

这是我的工作代码:

SELECT t1.col1, t1.col2, t1.col3, t1.col4, t1.col5, t1.type, t1.col6, 
t1.col7, t1.col8, t1.col9, t1.col10, t1.col11, t1.col12, t1.col13, efdt
FROM Table1 t1
LEFT JOIN( SELECT col1, col2, col3, col4, MAX(dtcol) as efdt --Left join on aggregated Table2
FROM Table2
GROUP BY col1, col2, col3, col4 ) t2
ON t2.col1 = t1.col1
AND t2.col2 = t1.col2
AND t2.col3 = CASE --There are 6 'types' in Table1
  WHEN t1.type = '1' THEN t1.col6
  WHEN t1.type = '2' THEN t1.col7
  WHEN t1.type = '3' THEN t1.col8
  WHEN t1.type = '4' THEN t1.col9
  WHEN t1.type = '5' THEN t1.col10
  WHEN t1.type = '6' THEN t1.col11 END;

现在我正尝试添加第四项比较。但是,此比较仅在t1.type'1''2'时存在,因此我希望在type不是'1'或{ {1}}。这是我尝试过的一些事情:

'2'

此代码可以编译,但是当AND t2.col4 = CASE WHEN t1.type = '1' THEN t1.col12 WHEN t1.type = '2' THEN t1.col13 END; 不等于efdtNULL时,t1.type就是'1',因为它不能加入{{ 1}}

'2'

此代码会导致“缺少表达式”错误

Table2

这段代码可以编译,老实说我认为这行得通。但是,当AND WHERE t1.type = '1' OR t1.type = '2' THEN t2.col4 = CASE WHEN t1.type = '1' THEN t1.col12 WHEN t1.type = '2' THEN t1.col13 END; 等于AND t2.col4 = CASE WHEN t1.type = '1' THEN t1.col12 WHEN t1.type = '2' THEN t1.col13 ELSE t2.col4 END; --Else, evaluate to 'True' efdt时,这导致NULLt1.type,但我不确定为什么。看来这样会导致这些行无法加入'1'

非常感谢您的帮助,谢谢!

2 个答案:

答案 0 :(得分:0)

您的方法错误。我认为如果没有case,这会更简单。相反:

AND
( (t1.type = '1' AND t2.col4 = t1.col12) OR
  (t1.type = '2' AND t2.col4 = t1.col13) OR
  t1.type NOT IN ('1', '2')
)

注意:这假设t1.type不是NULL(如果需要,可以将逻辑合并到比较中)。

答案 1 :(得分:0)

一些CREATE TABLE DDL和一些INSERT带有示例数据的语句确实会有所帮助。但这应该可行:

AND ( t2.col4 = CASE
  WHEN t1.type = '1' THEN t1.col12
  WHEN t1.type = '2' THEN t1.col13 END
     OR t1.type NOT IN ('1','2') )
; 

示例:

CREATE TABLE t1 ( type varchar2(1), col1 number,col2 number, col3 number, col4 number, col5 number, col6 number, col7 number, col8 number, col9 number, col10 number, col11 number, col12 number, col13 number );

CREATE TABLE t2 ( col1 number,col2 number, col3 number, col4 number, dtcol DATE );

insert into t1
select to_char(rownum), 1000 + (100*rownum) + 1, 1000 + (100*rownum) + 2, 1000 + (100*rownum) + 3
, 1000 + (100*rownum) + 4, 1000 + (100*rownum) + 5, 1000 + (100*rownum) + 6, 1000 + (100*rownum) + 7
, 1000 + (100*rownum) + 8, 1000 + (100*rownum) + 9, 1000 + (100*rownum) + 10, 1000 + (100*rownum) + 11
, 1000 + (100*rownum) + 12, 1000 + (100*rownum) + 13
from dual
connect by rownum <= 6;

insert into t2 values (1601, 1602, 1611, 9999, SYSDATE);
insert into t2 values (1101, 1102, 1106, 9999, SYSDATE);
insert into t2 values (1101, 1102, 1106, 1112, SYSDATE-5);

SELECT t1.col1, t1.col2, t1.col3, t1.col4, t1.col5, t1.type, t1.col6, 
t1.col7, t1.col8, t1.col9, t1.col10, t1.col11, t1.col12, t1.col13, efdt
FROM t1
LEFT JOIN( SELECT col1, col2, col3, col4, MAX(dtcol) as efdt --Left join on aggregated Table2
FROM t2
GROUP BY col1, col2, col3, col4 ) t2
ON t2.col1 = t1.col1
AND t2.col2 = t1.col2
AND t2.col3 = CASE --There are 6 'types' in Table1
  WHEN t1.type = '1' THEN t1.col6
  WHEN t1.type = '2' THEN t1.col7
  WHEN t1.type = '3' THEN t1.col8
  WHEN t1.type = '4' THEN t1.col9
  WHEN t1.type = '5' THEN t1.col10
  WHEN t1.type = '6' THEN t1.col11 END
AND ( t2.col4 = CASE
  WHEN t1.type = '1' THEN t1.col12
  WHEN t1.type = '2' THEN t1.col13 END
     OR t1.type NOT IN ('1','2') )
; 
+------+------+------+------+------+------+------+------+------+------+-------+-------+-------+-------+-----------+
| COL1 | COL2 | COL3 | COL4 | COL5 | TYPE | COL6 | COL7 | COL8 | COL9 | COL10 | COL11 | COL12 | COL13 |   EFDT    |
+------+------+------+------+------+------+------+------+------+------+-------+-------+-------+-------+-----------+
| 1101 | 1102 | 1103 | 1104 | 1105 |    1 | 1106 | 1107 | 1108 | 1109 |  1110 |  1111 |  1112 |  1113 | 08-AUG-19 |
| 1201 | 1202 | 1203 | 1204 | 1205 |    2 | 1206 | 1207 | 1208 | 1209 |  1210 |  1211 |  1212 |  1213 |           |
| 1301 | 1302 | 1303 | 1304 | 1305 |    3 | 1306 | 1307 | 1308 | 1309 |  1310 |  1311 |  1312 |  1313 |           |
| 1401 | 1402 | 1403 | 1404 | 1405 |    4 | 1406 | 1407 | 1408 | 1409 |  1410 |  1411 |  1412 |  1413 |           |
| 1501 | 1502 | 1503 | 1504 | 1505 |    5 | 1506 | 1507 | 1508 | 1509 |  1510 |  1511 |  1512 |  1513 |           |
| 1601 | 1602 | 1603 | 1604 | 1605 |    6 | 1606 | 1607 | 1608 | 1609 |  1610 |  1611 |  1612 |  1613 | 13-AUG-19 |
+------+------+------+------+------+------+------+------+------+------+-------+-------+-------+-------+-----------+

请注意,类型6行获取的非空EFDT,类型1行获取的EFDT与扩展(col4)条件匹配。