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_LOGHISTORY_LOG_DETAILED tables 以获得特定状态的日期,并设置为 OPENED_DATECLOSED_DATE (如果状态 1 ,则打开日期为 DATE 列,否则设置为 01.01.0001)

之后按 ORDER_NO 对这些记录进行分组并最大化日期值以获得实际 OPENED_DATECLOSED_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
;