从另一个中减去1个SQL

时间:2015-10-29 16:59:57

标签: sql oracle difference

我想从两个不同的SQL中获得差异。 我见过类似的问题,但无法让他们验证。 甲骨文。 这是我在下面的帮助下的决议;

select 
(TRUNC( "C__en_zw__V_EVENT_LOG_ENDDATE"."CREATE_TMSTMP" ) - NUMTODSINTERVAL( EXTRACT( DAY FROM TRUNC( "C__en_zw__V_EVENT_LOG_ENDDATE"."CREATE_TMSTMP" ) ), 'DAY' ) + INTERVAL '1' DAY + INTERVAL '1' MONTH - INTERVAL '1' DAY) "Month1",
sum(case when "C__en_zw__V_EVENT_LOG_ENDDATE"."EVENT_CD"='DSP_SUBMITTED' 
                and "C__en_zw__V_EVENT_LOG_ENDDATE"."DCN" IS NOT NULL
                THEN 1
                WHEN "C__en_zw__V_EVENT_LOG_ENDDATE"."EVENT_CD" ! ='DSP_SUBMITTED' 
                and "C__en_zw__V_EVENT_LOG_ENDDATE"."DCN" IS NOT NULL
                THEN -1
                 ELSE 0
           END)                "DCN"
 from 
"CJIMRPT"."V_EVENT_LOG_ENDTIME" "C__en_zw__V_EVENT_LOG_ENDDATE", 
"CJIMRPT"."V_REMAND" "C__en_zw__V_REMAND"
 where "C__en_zw__V_REMAND"."DCN"<>"C__en_zw__V_REMAND"."DOC_ID" and 
"C__en_zw__V_EVENT_LOG_ENDDATE"."EVENT_CD"in('DSP_SUBMITTED','CPIC_PUBLISHING', 'DSP_PUBLISHED', 'DSP_PURGED', 'DSP_ARCHIVED', 'DSP_REJECTED', 'DSP_IDENT_ONLY') and 
not "C__en_zw__V_EVENT_LOG_ENDDATE"."DCN" is null and 
"C__en_zw__V_REMAND"."REMAND_ID"="C__en_zw__V_EVENT_LOG_ENDDATE"."REMAND_ID" and 
"C__en_zw__V_EVENT_LOG_ENDDATE"."CREATE_TMSTMP">=CASE WHEN EXTRACT( DAY FROM (TRUNC( SYSDATE ) - NUMTODSINTERVAL( EXTRACT( DAY FROM TRUNC( SYSDATE ) ), 'DAY' ) + INTERVAL '1' DAY) - NUMTODSINTERVAL( EXTRACT( DAY FROM (TRUNC( SYSDATE ) - NUMTODSINTERVAL( EXTRACT( DAY FROM TRUNC( SYSDATE ) ), 'DAY' ) + INTERVAL '1' DAY) ), 'DAY' ) + INTERVAL '1' DAY + NUMTOYMINTERVAL( -4, 'MONTH' ) + INTERVAL '1' MONTH - INTERVAL '1' DAY ) < EXTRACT( DAY FROM (TRUNC( SYSDATE ) - NUMTODSINTERVAL( EXTRACT( DAY FROM TRUNC( SYSDATE ) ), 'DAY' ) + INTERVAL '1' DAY) ) THEN (TRUNC( SYSDATE ) - NUMTODSINTERVAL( EXTRACT( DAY FROM TRUNC( SYSDATE ) ), 'DAY' ) + INTERVAL '1' DAY) - NUMTODSINTERVAL( EXTRACT( DAY FROM (TRUNC( SYSDATE ) - NUMTODSINTERVAL( EXTRACT( DAY FROM TRUNC( SYSDATE ) ), 'DAY' ) + INTERVAL '1' DAY) ), 'DAY' ) + INTERVAL '1' DAY + NUMTOYMINTERVAL( -4, 'MONTH' ) + INTERVAL '1' MONTH - INTERVAL '1' DAY ELSE (TRUNC( SYSDATE ) - NUMTODSINTERVAL( EXTRACT( DAY FROM TRUNC( SYSDATE ) ), 'DAY' ) + INTERVAL '1' DAY) + NUMTOYMINTERVAL( -4, 'MONTH' ) END and 
"C__en_zw__V_EVENT_LOG_ENDDATE"."CREATE_TMSTMP"<(TRUNC( SYSDATE ) - NUMTODSINTERVAL( EXTRACT( DAY FROM TRUNC( SYSDATE ) ), 'DAY' ) + INTERVAL '1' DAY)
group by (TRUNC( "C__en_zw__V_EVENT_LOG_ENDDATE"."CREATE_TMSTMP" ) - NUMTODSINTERVAL( EXTRACT( DAY FROM TRUNC( "C__en_zw__V_EVENT_LOG_ENDDATE"."CREATE_TMSTMP" ) ), 'DAY' ) + INTERVAL '1' DAY + INTERVAL '1' MONTH - INTERVAL '1' DAY)

3 个答案:

答案 0 :(得分:3)

我认为您的问题与MINUS运算符无关,但如果我理解正确,您需要两个查询的记录计数的减法结果。这可以简单描述如下 -

select (select count(*) from dual) - (select count(*) from dual)
 from dual;

您需要将select count(*) from dual替换为您自己的count(*)个问题。

请注意,如果您首先应用MINUS运营商,正如@kevinsky在回答中所说,然后执行count(*)您的结果可能不合适或不可取(通过下面的例子说明) -

 select count(*)
 from (
         select * from  (select 1 from dual
                             union
                             select 2 from dual
                             union
                             select 3 from dual
                             union
                             select 4 from dual)
         minus
          select * from (select 1 from dual
                              union
                             select 2 from dual
                             union
                             select 5 from dual
                             union
                             select 6 from dual));
 --Retruns result as 2

 select (select count(*)
                   from  (select 1 from dual
                             union
                             select 2 from dual
                             union
                             select 3 from dual
                             union
                             select 4 from dual))
         -
        (select count(*)
                   from (select 1 from dual
                              union
                             select 2 from dual
                             union
                             select 5 from dual
                             union
                             select 6 from dual)) cnt
 from dual;     
--Returns result as 0

答案 1 :(得分:2)

使用MINUS运算符从另一个或INTERSECT中减去一组记录以查找公共元素。这两组必须具有相同的列数。 只需将 - 替换为MINUS关键字。

Oracle的例子

SELECT product_id FROM inventories
MINUS
SELECT product_id FROM order_items;

答案 2 :(得分:2)

由于看起来两个查询之间的唯一区别是正在考虑event_cd,您可以将其简化为一个查询,它可以获取您已识别的所有event_cds,然后将&1加1 39; DSP_SUBMITTED&#39;行(您的顶部查询)和-1为其他event_Cds(您的底部查询)。

我使用CASE检查EVENT_CD以查看这是向上计数还是向下计数,还检查&#34; C__en_zw__V_EVENT_LOG_ENDDATE&#34;。&#34; DCN&#34; IS NOT NULL,因为您给定的COUNT(DCN)逻辑不计算空值,所以我需要复制该行为。

select sum(case when "C__en_zw__V_EVENT_LOG_ENDDATE"."EVENT_CD"='DSP_SUBMITTED' 
                and "C__en_zw__V_EVENT_LOG_ENDDATE"."DCN" IS NOT NULL
                THEN 1
                WHEN "C__en_zw__V_EVENT_LOG_ENDDATE"."EVENT_CD" ! ='DSP_SUBMITTED' 
                and "C__en_zw__V_EVENT_LOG_ENDDATE"."DCN" IS NOT NULL
                THEN -1
                 ELSE 0
           END)                "DCN"
 from 
"CJIMRPT"."V_EVENT_LOG_ENDTIME" "C__en_zw__V_EVENT_LOG_ENDDATE", 
"CJIMRPT"."V_REMAND" "C__en_zw__V_REMAND"
 where "C__en_zw__V_REMAND"."DCN"<>"C__en_zw__V_REMAND"."DOC_ID" and 
"C__en_zw__V_EVENT_LOG_ENDDATE"."EVENT_CD"in('DSP_SUBMITTED','CPIC_PUBLISHING', 'DSP_PUBLISHED', 'DSP_PURGED', 'DSP_ARCHIVED', 'DSP_REJECTED', 'DSP_IDENT_ONLY') and 
not "C__en_zw__V_EVENT_LOG_ENDDATE"."DCN" is null and 
"C__en_zw__V_REMAND"."REMAND_ID"="C__en_zw__V_EVENT_LOG_ENDDATE"."REMAND_ID"