在我们的交易中,我们有两个步骤 为此,我们有TxnStepDetails表。
TxnId stepId status retryCount
100 step1 0 1
100 step2 0 1
101 step1 0 1
我的要求是我希望我拥有step2的所有交易对应于step1。 我正在使用以下查询。
select a.txnid txnid,
a.stepid as stepida,
a.status as statusa,
b.stepid as stepidb,
b.status as statusb
from txnstepdetails a left join txnstepdetails b on a.txnid = b.txnid
where a.retrycount > 0
and a.stepid = 'step1'
and b.stepid = 'step2';
输出:
TxnId stepIdA statusA stepIdB statusB
100 step1 0 step2 0
但我的预期输出是:
TxnId stepIdA statusA stepIdB statusB
100 step1 0 step2 0
101 step1 0 null null
我搜索了 LEFT INNER JOIN 的结果,但没有这样的事情。 我在查询中做了哪些更改,以便获得所需的结果。
答案 0 :(得分:2)
在外部联接表上添加where
条件会将外部联接转换为内部联接。您需要将该条件移至JOIN
select a.TxnId TxnId,
a.stepId as stepIdA,
a.status as statusA,
b.stepI as stepIdB,
b.status as statusB
from TxnStepDetails a
LEFT JOIN TxnStepDetails b
on a.TxnId = b.TxnId
and b.stepId='step2'
where and a.retryCount>0
and a.stepId='step1';
答案 1 :(得分:0)
SELECT TxnId,
regexp_substr(stepId, '[^,]+', 1, 1) as stepIdA,
regexp_substr(status, '[^,]+', 1, 1) as statusA,
regexp_substr(stepId, '[^,]+', 1, 2) as stepIdB,
regexp_substr(status, '[^,]+', 1, 2) as statusB
From
(
SELECT
TxnId ,
LISTAGG(stepId, ', ') WITHIN GROUP (ORDER BY TxnId) AS stepId,
LISTAGG(status, ', ') WITHIN GROUP (ORDER BY TxnId) AS status
FROM table1
GROUP BY TxnId
)
输出
TXNID STEPIDA STATUSA STEPIDB STATUSB
100 step1 0 step2 0
101 step1 0 (null) (null)
演示链接
答案 2 :(得分:0)
请检查oracle中的LAG(分析函数)。
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions070.htm
这将返回相应的值作为最后一步
SELECT txnid, stepid, status, LAG(stepid, 1, 0) OVER (PARTITION BY txnid ORDER BY ?) AS "stepiIdB", LAG(status, 1, 0) OVER (PARTITION BY txnid ORDER BY ?) AS "statusB"
FROM txnstepdetails;
这将为您提供一个结果集,其中列出了具有相应最后一个stepid状态的所有步骤。您需要定义一个命令,以便为oracle提供一个提示,以便结果集必须如何排序,例如创立日期。否则对于dbms,不清楚step1是在step2之前是时间还是以其他顺序。 Oracle不承诺选择返回日期的顺序与插入顺序相同。如果您想要按时间顺序,您必须添加一个时间戳列以便对其进行订购。