[英]Outer Joins with Multiple Conditions in Oracle Join Syntax
I have the tables below我有下面的表格
create table xx_base_tbl
(
tbl_id number
, trx_num varchar2(100)
);
create table xx_dtl_tbl
(
dtl_id number
, tbl_id number
, category varchar2(100)
, attribute1 varchar2(100)
);
insert into xx_base_tbl (tbl_id, trx_num) values (1, 'trx 1');
insert into xx_base_tbl (tbl_id, trx_num) values (2, 'trx 2');
insert into xx_base_tbl (tbl_id, trx_num) values (3, 'trx 3');
insert into xx_base_tbl (tbl_id, trx_num) values (4, 'trx 4');
insert into xx_base_tbl (tbl_id, trx_num) values (5, 'trx 5');
insert into xx_dtl_tbl (dtl_id, tbl_id, category, attribute1) values (1, 1, null, 'SAMPLE');
insert into xx_dtl_tbl (dtl_id, tbl_id, category, attribute1) values (2, 1, null, 'hello');
insert into xx_dtl_tbl (dtl_id, tbl_id, category, attribute1) values (3, 2, 'PREPAYMENT', 'this is not a value');
insert into xx_dtl_tbl (dtl_id, tbl_id, category, attribute1) values (4, 2, 'PREPAYMENT', 1);
insert into xx_dtl_tbl (dtl_id, tbl_id, category, attribute1) values (5, 3, 'PREPAYMENT', 2);
insert into xx_dtl_tbl (dtl_id, tbl_id, category, attribute1) values (6, 3, 'PREPAYMENT', 1);
insert into xx_dtl_tbl (dtl_id, tbl_id, category, attribute1) values (7, 3, 'SAMPLE', 15678);
insert into xx_dtl_tbl (dtl_id, tbl_id, category, attribute1) values (8, 4, 'PREPAYMENT', 1);
insert into xx_dtl_tbl (dtl_id, tbl_id, category, attribute1) values (9, 4, 'PREPAYMENT', NULL);
insert into xx_dtl_tbl (dtl_id, tbl_id, category, attribute1) values (10, 5, 'PREPAYMENT', null);
insert into xx_dtl_tbl (dtl_id, tbl_id, category, attribute1) values (11, 5, 'SAMPLE', 'YEY');
I am using the ANSI Syntax below to outer join xx_dtl_tbl to another xx_base_tbl show only CATEGORY with PREPAYMENT and numeric values only.我正在使用下面的 ANSI 语法将 xx_dtl_tbl 外部连接到另一个 xx_base_tbl 仅显示具有 PREPAYMENT 和数值的 CATEGORY。 then use
LISTAGG()
to aggregate the results into a single row然后使用
LISTAGG()
将结果聚合到一行中
SELECT
xx1.trx_num,
LISTAGG(xx3.trx_num, ',') WITHIN GROUP(
ORDER BY
xx3.trx_num
) prepayment
FROM
xx_base_tbl xx1
INNER JOIN xx_dtl_tbl xx2 ON xx1.tbl_id = xx2.tbl_id
LEFT JOIN xx_base_tbl xx3 ON (to_number(xx2.attribute1) = xx3.tbl_id and length(TRIM(translate(xx2.attribute1, ' +-.0123456789', ' '))) IS NULL)
GROUP BY
xx1.trx_num
The result looks fine:结果看起来不错:
TRX_NUM PREPAYMENT
------- -------------
trx 1
trx 2 trx 1
trx 3 trx 1,trx 2
trx 4 trx 1
trx 5
However, when i use SQL Developer's tool to change the syntax to Oracle Join Syntax , it get the below result:但是,当我使用SQL 开发工具将语法更改为 Oracle Join Syntax时,得到以下结果:
SELECT
xx1.trx_num,
LISTAGG(xx3.trx_num, ',') WITHIN GROUP(
ORDER BY
xx3.trx_num
) prepayment
FROM
xx_base_tbl xx1,
xx_dtl_tbl xx2,
xx_base_tbl xx3
WHERE
xx1.tbl_id = xx2.tbl_id
AND to_number(xx2.attribute1) = xx3.tbl_id (+)
AND ( length(TRIM(translate(xx2.attribute1, ' +-.0123456789', ' '))) IS NULL )
GROUP BY
xx1.trx_num
The result changed:结果变了:
TRX_NUM PREPAYMENT
------- -------------
trx 2 trx 1
trx 3 trx 1,trx 2
trx 4 trx 1
trx 5
the trx 1 row is suddenly missing. trx 1 行突然丢失。 How can I write this in Oracle Syntax?
我怎样才能在 Oracle 语法中写这个?
This query is not so easy to transform to old syntax.这个查询不太容易转换为旧语法。 Something which worked for me is:
对我有用的是:
select a.trx_num,
listagg(b.trx_num, ',') within group (order by b.trx_num) prepayment
from (
select trx_num, attribute1,
case when trim(translate(xx2.attribute1, ' +-.0123456789', ' ')) is null
then to_number(xx2.attribute1)
end attr_num
from xx_base_tbl xx1, xx_dtl_tbl xx2
where xx1.tbl_id = xx2.tbl_id) a,
xx_base_tbl b
where a.attr_num = b.tbl_id (+)
group by a.trx_num
Two steps, in first create joining column using case when
in subquery, then use it in main query.两个步骤,首先在子查询中使用
case when
创建连接列,然后在主查询中使用它。
Edit:编辑:
Above query may be simplified to:上面的查询可以简化为:
select xx1.trx_num,
listagg(xx3.trx_num, ',') within group (order by xx3.trx_num) prepayment
from xx_base_tbl xx1, xx_dtl_tbl xx2, xx_base_tbl xx3
where xx1.tbl_id = xx2.tbl_id
and case when trim(translate(xx2.attribute1, ' +-.0123456789', ' ')) is null
then to_number(xx2.attribute1)
end = xx3.tbl_id(+)
group by xx1.trx_num
The syntax that is used in your first query is ANSI standard joins and properly works with oracle.在您的第一个查询中使用的语法是 ANSI 标准连接,并且可以与 oracle 一起正常工作。
Second query's syntax is old SQL-92 standard and should be avoided.第二个查询的语法是旧的 SQL-92 标准,应该避免使用。 Also, it is hard to understand and handle.
此外,它很难理解和处理。
By the way, your second query will need some extra clauses as follows:顺便说一句,您的第二个查询将需要一些额外的子句,如下所示:
WHERE
xx1.tbl_id = xx2.tbl_id
AND to_number(xx2.attribute1) = xx3.tbl_id (+)
AND (xx3.tbl_id is null -- this extra OR condition is needed with below condition
or ( length(TRIM(translate(xx2.attribute1, ' +-.0123456789', ' '))) IS NULL )
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.