ORACLE SQL - 来自同一 table 的多个 JOIN
ORACLE SQL - multiple JOINs from same table
我在一个 table 中有与 material 事务相关的数据和日志历史记录 header 与 material 相关的数据在另一个 table 和详细日志中历史数据第三table。我正在尝试获取与 material table 匹配的不同状态更新日期,但我得到了一个 material 交易
的重复行
原始 material 交易 table:
ORDER_NO
MATERIAL
QTY
0001
MAT01
2
0002
MAT02
5
原始日志历史记录Header事务table:
ORDER_NO
LOG_ID
0001
1001
0001
1002
状态代码 1 表示已打开,代码 2 表示已关闭
详细日志历史记录table:
LOG_ID
STATUS_CODE
DATE
1001
1
11/12/2021
1002
2
15/12/2021
使用以下 SQL 查询:
SELECT
TO_CHAR (m.order_no) order_no,
m.material,
a.date opened_date,
ab.closed_date
FROM MATERIAL_TRANSACTIONS m
INNER JOIN HISTORY_LOG t
ON m.ORDER_NO = t.ORDER_NO
INNER JOIN HISTORY_LOG_DETAILED a
ON t.LOG_ID = a.LOG_ID
AND a.STATUS_CODE = '1'
INNER JOIN HISTORY_LOG_DETAILED ab
ON t.LOG_ID = ab.LOG_ID
AND ab.STATUS_CODE = '2'
我得到以下结果:
ORDER_NO
MATERIAL
QTY
OPENED_DATE
CLOSED_DATE
0001
MAT01
2
11/12/2021
0001
MAT01
2
15/12/2021
我想将状态日期显示在如下同一行中:
ORDER_NO
MATERIAL
QTY
OPENED_DATE
CLOSED_DATE
0001
MAT01
2
11/12/2021
15/12/2021
如果能得到所有帮助,我将不胜感激,如果已经有类似问题的主题,我将深表歉意。
只是一个想法:
我加入了 HISTORY_LOG
和 HISTORY_LOG_DETAILED
tables 以获得特定状态的日期,并设置为 OPENED_DATE
和 CLOSED_DATE
(如果状态 1 ,则打开日期为 DATE
列,否则设置为 01.01.0001
)
之后按 ORDER_NO
对这些记录进行分组并最大化日期值以获得实际 OPENED_DATE
和 CLOSED_DATE
。
终于加入了这个子查询 MATERIAL_TRANSACTIONS
table :
SELECT
TO_CHAR (M.ORDER_NO) ORDER_NO,
M.MATERIAL,
QTY,
L_T.OPENED_DATE,
L_T.CLOSED_DATE
FROM MATERIAL_TRANSACTIONS M
INNER JOIN
(
SELECT L.ORDER_NO ,
MAX( CASE WHEN LD.STATUS_CODE = 1 THEN LD.DATE ELSE TO_DATE('01.01.0001','dd.mm.yyyy') END ) OPENED_DATE
MAX( CASE WHEN LD.STATUS_CODE = 2 THEN LD.DATE ELSE TO_DATE('01.01.0001','dd.mm.yyyy') END ) CLOSED_DATE
FROM
HISTORY_LOG L
INNER JOIN HISTORY_LOG_DETAILED LD ON LD.LOG_ID = L.LOG_ID
GROUP BY L.ORDER_NO
) L_T on L_T.ORDER_NO = M.ORDER_NO
注意:我没有测试。所以可能会有小的语法错误。请检查它并为了更好的帮助添加一个 fiddle 以便我可以测试我的查询
您的问题出现是因为您加入了历史记录 table,其中包含订单的 2 条记录。如果你使用 2 个内联 tables 恰好包含 1 个记录,你可以将其展平。
with opened_dates as (
select h.order_id, d.date
from history h
inner join details d on h.log_id = d.log_id and d.status_code = '1'
), closed_dates as (
select h.order_id, d.date
from history h
inner join details d on h.log_id = d.log_id and d.status_code = '2'
)
select to_char (m.order_no) order_no,
m.material,
o.date opened_date,
c.date closed_date
from material_transactions m
join opened_dates o on m.order_no = o.order_no
join closed_dates c on m.order_no = c.order_no
;
我在一个 table 中有与 material 事务相关的数据和日志历史记录 header 与 material 相关的数据在另一个 table 和详细日志中历史数据第三table。我正在尝试获取与 material table 匹配的不同状态更新日期,但我得到了一个 material 交易
的重复行原始 material 交易 table:
ORDER_NO | MATERIAL | QTY |
---|---|---|
0001 | MAT01 | 2 |
0002 | MAT02 | 5 |
原始日志历史记录Header事务table:
ORDER_NO | LOG_ID |
---|---|
0001 | 1001 |
0001 | 1002 |
状态代码 1 表示已打开,代码 2 表示已关闭
详细日志历史记录table:
LOG_ID | STATUS_CODE | DATE |
---|---|---|
1001 | 1 | 11/12/2021 |
1002 | 2 | 15/12/2021 |
使用以下 SQL 查询:
SELECT
TO_CHAR (m.order_no) order_no,
m.material,
a.date opened_date,
ab.closed_date
FROM MATERIAL_TRANSACTIONS m
INNER JOIN HISTORY_LOG t
ON m.ORDER_NO = t.ORDER_NO
INNER JOIN HISTORY_LOG_DETAILED a
ON t.LOG_ID = a.LOG_ID
AND a.STATUS_CODE = '1'
INNER JOIN HISTORY_LOG_DETAILED ab
ON t.LOG_ID = ab.LOG_ID
AND ab.STATUS_CODE = '2'
我得到以下结果:
ORDER_NO | MATERIAL | QTY | OPENED_DATE | CLOSED_DATE |
---|---|---|---|---|
0001 | MAT01 | 2 | 11/12/2021 | |
0001 | MAT01 | 2 | 15/12/2021 |
我想将状态日期显示在如下同一行中:
ORDER_NO | MATERIAL | QTY | OPENED_DATE | CLOSED_DATE |
---|---|---|---|---|
0001 | MAT01 | 2 | 11/12/2021 | 15/12/2021 |
如果能得到所有帮助,我将不胜感激,如果已经有类似问题的主题,我将深表歉意。
只是一个想法:
我加入了 HISTORY_LOG
和 HISTORY_LOG_DETAILED
tables 以获得特定状态的日期,并设置为 OPENED_DATE
和 CLOSED_DATE
(如果状态 1 ,则打开日期为 DATE
列,否则设置为 01.01.0001
)
之后按 ORDER_NO
对这些记录进行分组并最大化日期值以获得实际 OPENED_DATE
和 CLOSED_DATE
。
终于加入了这个子查询 MATERIAL_TRANSACTIONS
table :
SELECT
TO_CHAR (M.ORDER_NO) ORDER_NO,
M.MATERIAL,
QTY,
L_T.OPENED_DATE,
L_T.CLOSED_DATE
FROM MATERIAL_TRANSACTIONS M
INNER JOIN
(
SELECT L.ORDER_NO ,
MAX( CASE WHEN LD.STATUS_CODE = 1 THEN LD.DATE ELSE TO_DATE('01.01.0001','dd.mm.yyyy') END ) OPENED_DATE
MAX( CASE WHEN LD.STATUS_CODE = 2 THEN LD.DATE ELSE TO_DATE('01.01.0001','dd.mm.yyyy') END ) CLOSED_DATE
FROM
HISTORY_LOG L
INNER JOIN HISTORY_LOG_DETAILED LD ON LD.LOG_ID = L.LOG_ID
GROUP BY L.ORDER_NO
) L_T on L_T.ORDER_NO = M.ORDER_NO
注意:我没有测试。所以可能会有小的语法错误。请检查它并为了更好的帮助添加一个 fiddle 以便我可以测试我的查询
您的问题出现是因为您加入了历史记录 table,其中包含订单的 2 条记录。如果你使用 2 个内联 tables 恰好包含 1 个记录,你可以将其展平。
with opened_dates as (
select h.order_id, d.date
from history h
inner join details d on h.log_id = d.log_id and d.status_code = '1'
), closed_dates as (
select h.order_id, d.date
from history h
inner join details d on h.log_id = d.log_id and d.status_code = '2'
)
select to_char (m.order_no) order_no,
m.material,
o.date opened_date,
c.date closed_date
from material_transactions m
join opened_dates o on m.order_no = o.order_no
join closed_dates c on m.order_no = c.order_no
;