繁体   English   中英

如何在合并语句中编写 case 表达式以打印所需的结果

[英]How to write case expression inside merge statement to print the desired result

    CREATE TABLE DELIGATE_DETAILS_MAIN 
       (    E_ID NUMBER(10,0), 
        COMPLETED_DATE TIMESTAMP (6), 
         CONSTRAINT PK_DELIGATE_DETAILS_MAIN PRIMARY KEY (E_ID));

Insert into deligate_details_main (E_ID,COMPLETED_DATE) values (1,to_timestamp('13-12-21 6:05:23.991000000 PM','DD-MM-RR fmHH12:fmMI:SSXFF AM'));
Insert into deligate_details_main (E_ID,COMPLETED_DATE) values (2,to_timestamp('13-12-21 6:05:24.019000000 PM','DD-MM-RR fmHH12:fmMI:SSXFF AM'));
Insert into deligate_details_main (E_ID,COMPLETED_DATE) values (3,to_timestamp('13-12-21 6:05:24.029000000 PM','DD-MM-RR fmHH12:fmMI:SSXFF AM'));
Insert into deligate_details_main (E_ID,COMPLETED_DATE) values (4,to_timestamp('13-12-21 10:46:00.015000000 PM','DD-MM-RR fmHH12:fmMI:SSXFF AM'));

CREATE TABLE CONTROL_MAIN 
   (    E_ID NUMBER(10,0), 
    E_SPEC VARCHAR2(30 BYTE), 
     CONSTRAINT PK_CONTROL_MAIN PRIMARY KEY (E_ID));
     

Insert into CONTROL_MAIN (E_ID,E_SPEC) values (1,'SAP1');
Insert into CONTROL_MAIN (E_ID,E_SPEC) values (2,'FSAP');
Insert into CONTROL_MAIN (E_ID,E_SPEC) values (3,'SAP2');
Insert into CONTROL_MAIN (E_ID,E_SPEC) values (4,'SAP1-480');

CREATE TABLE QUESTION 
   (    E_ID NUMBER(10,0), 
    QUEST VARCHAR2(30 BYTE), 
     CONSTRAINT PK_QUESTION PRIMARY KEY (E_ID));
     

Insert into QUESTION (E_ID,QUEST) values (1,'Yes');
Insert into QUESTION (E_ID,QUEST) values (2,'No');
Insert into QUESTION (E_ID,QUEST) values (3,'Yes');
Insert into QUESTION (E_ID,QUEST) values (4,'Yes');

CREATE TABLE DELIGATE_DETAILS_TRANS 
   (    D_ID NUMBER(10,0), 
    E_ID NUMBER(10,0), 
    COMPLETED_DATE_TRANS DATE, 
    OWNER_DETAIL VARCHAR2(30 BYTE), 
     CONSTRAINT PK_DELIGATE_DETAILS_TRANS PRIMARY KEY (D_ID),
     CONSTRAINT FK_E_ID FOREIGN KEY (E_ID)
      REFERENCES TAM.DELIGATE_DETAILS_MAIN (E_ID));

试图:

MERGE INTO deligate_details_trans t USING ( SELECT
    ddm.e_id,
    ddm.completed_date
FROM
    deligate_details_main ddm
JOIN control_main cm ON ( cm.e_id = ddm.e_id AND cm.e_spec LIKE %'SAP'% )
    JOIN question      q ON ( q.e_id = ddm.e_id
                         AND q.quest = 'Yes' )
          ) s
    on (t.e_id = s.e_id)
    when not matched then
      insert (d_id,e_id, completed_date_trans, owner_detail)
      values (
    deligate_details_trans_sq.nextval,
    s.e_id,
    CAST(s.completed_date AS DATE),
--Here need to insert owner detail from control main
--If it is SAP1 or SAP2 then it will insert SAP1 or SAP2
--If it is SAP1-480 then it should insert SAP3);

预期 output:

做过 E_ID COMPLETED_DATE_TRANS OWNER_DETAIL
1 1 13-12-21 SAP1
2 3 13-12-21 SAP2
3 4 13-12-21 SAP3

对于 e_id 1:基于 control_main 和问题表的连接条件。 数据应插入到 deligate_details_trans 表中,所有者详细信息应为 SAP1。

对于 e_id 2:基于 control_main 和问题表的连接条件。 数据不匹配,因此不应将其插入到 trans 表中。

对于 e_id 3:基于 control_main 和问题表的连接条件。 数据应插入到 deligate_details_trans 表中,所有者详细信息应为 SAP2。

对于 e_id 4,它应该检查控制主表,如果它是 SAP1-480,那么它应该插入 SAP3,对于其他人,应该从 control_main 表中插入相应的所有者详细信息

如果要在插入的values子句中使用 case 表达式,则需要在using子句中公开控制表值:

MERGE INTO deligate_details_trans t
USING (
    SELECT
        ddm.e_id,
        ddm.completed_date,
        cm.e_spec
    FROM
        deligate_details_main ddm
    JOIN control_main cm ON ( cm.e_id = ddm.e_id AND cm.e_spec LIKE '%SAP%' )
    JOIN question      q ON ( q.e_id = ddm.e_id
                         AND q.quest = 'Yes' )
) s
ON (t.e_id = s.e_id)
WHEN NOT MATCHED THEN INSERT (
    d_id,e_id, completed_date_trans, owner_detail
)
VALUES (
    deligate_details_trans_sq.nextval,
    s.e_id,
    CAST(s.completed_date AS DATE),
    CASE s.e_spec
        WHEN 'SAP1' THEN 'SAP1'
        WHEN 'SAP2' THEN 'SAP2'
        WHEN 'SAP1-480' THEN 'SAP3'
    END
);

或者将 case 表达式移到using子句中,为其指定别名,然后在values子句中引用该别名:

MERGE INTO deligate_details_trans t
USING (
    SELECT
        ddm.e_id,
        ddm.completed_date,
        CASE cm.e_spec
            WHEN 'SAP1' THEN 'SAP1'
            WHEN 'SAP2' THEN 'SAP2'
            WHEN 'SAP1-480' THEN 'SAP3'
        END AS owner_detail
    FROM
        deligate_details_main ddm
    JOIN control_main cm ON ( cm.e_id = ddm.e_id AND cm.e_spec LIKE '%SAP%' )
    JOIN question      q ON ( q.e_id = ddm.e_id
                         AND q.quest = 'Yes' )
) s
ON (t.e_id = s.e_id)
WHEN NOT MATCHED THEN INSERT (
    d_id,e_id, completed_date_trans, owner_detail
)
VALUES (
    deligate_details_trans_sq.nextval,
    s.e_id,
    CAST(s.completed_date AS DATE),
    s.owner_detail
);

db<>fiddle显示两者(将%'SAP'%更改为'%SAP%' ,并添加了序列创建)。


我不确定为什么你在一个表中有一个时间戳,而在另一个表中有一个日期,而且你不需要显式转换(尽管它没有伤害)。 但是,如果您这样做是因为您只对日期部分感兴趣,那么您应该知道 Oracle 日期仍然具有时间组件,即使它没有以您的 DD-MM-YY 格式或 db< >fiddle 的默认 DD-MON-YY 格式。 如果您想“丢失”时间部分,您可以截断日期 (DD) 组件的值, 如此 db<>fiddle 所示,它会更改显示格式,以便您可以看到差异。 但是您可能想保留时间-在这种情况下,请忽略这部分...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM