当两个或多个条件成立时如何取消否定

时间:2018-04-26 11:13:20

标签: sql oracle

在下表中,每行代表一个条件。我想要得到的是,如果给定的条件是真的,我将需要得到它的否定。 我遇到的问题是,当我得到否定时,一些所需的数据就会被删除。

我尝试的方法如下。

请在下面找到我写过的查询。

s_r d_m c_m o_s b_s d_w r_n
SW  SW  DM  A   A       35RE%
SW  SW  DM  B   B       35RE%
SW  SW  DM      B   A   
SW  SW  DM      A   B   

EB  SW  DM  A   A       35RE%
EB  SW  DM  B   B       35RE%
EB  SW  DM      B   A   
EB  SW  DM      A   B   


SELECT *
  FROM e_t t1
 WHERE ( (t1.a_date >= '16-Mar-2018' AND t1.a_date <= '31-Mar-2018')
        OR (t1.r_date >= '16-Mar-2018' AND t1.r_date <= '31-Mar-2018'))
       AND t1.a_m = 'NO'
       AND ( (    t1.s_r IN ('EB', 'PH', 'PT', 'SW')
              AND t1.d_m IN ('DM', 'SW')
              AND t1.c_m = 'SW')
            OR (t1.s_r IN ('PH', 'PT') AND t1.d_m = 'SW' AND t1.c_m = 'DM')
            OR (    (t1.s_r = 'EB' AND t1.d_m = 'SW' AND t1.c_m = 'DM')
                AND (b_s != 'A' AND d_w != 'B')
                AND (b_s != 'B' AND d_w != 'A'))
            OR ( (    t1.s_r = 'SW'
                  AND t1.d_m = 'SW'
                  AND t1.c_m = 'DM'
                  AND t1.d_w NOT IN ('A', 'B'))
                AND o_s != 'A'
                AND r_n != '35RE%'))

按要求更新

以下查询是根据上表的第一行设计的。

SELECT * FROM  e_t t1 WHERE t1.s_r = 'SW'
         AND t1.d_m = 'SW'
         AND t1.c_m = 'DM'
         AND t1.d_w IN ('A', 'B')



A_M S_R D_M C_M B_S D_W
NO  SW  SW  DM  A   A
NO  SW  SW  DM  A   A
NO  SW  SW  DM  A   A
NO  SW  SW  DM  B   A
NO  SW  SW  DM  B   A
NO  SW  SW  DM  B   A
NO  SW  SW  DM  B   A

通过我的意思否定,我不希望这个结果出现在我的最终结果中。为此,我所做的就是以下内容。

SELECT * FROM  e_t t1 WHERE t1.s_r = 'SW'
         AND t1.d_m = 'SW'
         AND t1.c_m = 'DM'
         AND t1.d_w **NOT** IN ('A', 'B')

希望上面的解释清楚你的怀疑。

Update 27/04/2018

感谢所有帮助过目前的人。基于Ponder Stibbons,我更新了查询如下。但是这个查询在正确获取休息时删除了5个必需的数据行。

根据下面的条件表,我想采取否定并使用以下内容。

s_r d_m c_m o_s b_s d_w r_n
EB  SW  DM      B   A   
EB  SW  DM      A   B   

 (s_r, d_m, c_m, b_s, d_w)      not in 
    (('EB', 'SW', 'DM', 'B', 'A'),('EB', 'SW', 'DM', 'A', 'B'))

但这会删除以下数据集。我无法弄清楚原因。

s_r d_m c_m o_s b_s d_w r_n
EB  SW  DM          A 

此外,由于我无法解决以下问题,

(s_r, d_m, c_m, o_s, b_s, r_n) not in (('SW', 'SW', 'DM', 'A', 'A', '35RE%')

我使用了单独的查询并从主集中获取了MINUS。

2 个答案:

答案 0 :(得分:0)

如果我理解正确,你可以使用它:

select * 
  from eft_txn_details 
  where (s_r, d_m, c_m, o_s, b_s, r_n) not in (('SW', 'SW', 'DM', 'A', 'A', '35RE'))
    and (s_r, d_m, c_m, o_s, b_s, r_n) not in (('SW', 'SW', 'DM', 'B', 'B', '35RE'))
    and (s_r, d_m, c_m, b_s, d_w)      not in (('SW', 'SW', 'DM', 'B', 'A'))
    and (s_r, d_m, c_m, b_s, d_w)      not in (('SW', 'SW', 'DM', 'A', 'B'))
    and (s_r, d_m, c_m, o_s, b_s, r_n) not in (('EB', 'SW', 'DM', 'A', 'A', '35RE'))
    and (s_r, d_m, c_m, o_s, b_s, r_n) not in (('EB', 'SW', 'DM', 'B', 'B', '35RE'))
    and (s_r, d_m, c_m, b_s, d_w)      not in (('EB', 'SW', 'DM', 'B', 'A'))
    and (s_r, d_m, c_m, b_s, d_w)      not in (('EB', 'SW', 'DM', 'A', 'B'))

添加日期等条件。您可以简化此语法,但这样更容易阅读,至少对我而言。

答案 1 :(得分:0)

感谢Ponder Stibbons,我能够得到理想的结果,但我不确定它是否是最佳方式。如果任何一个人可以提出更好的建议,那真的是非常具体的。

/* Formatted on 27/04/2018 11:19:46 AM (QP5 v5.150) */
SELECT *
  FROM e_t t1
 WHERE ( (t1.a_date >= '16-Mar-2018'
              AND t1.a_date <= '31-Mar-2018')
            OR (t1.r_date >= '16-Mar-2018'
                AND t1.r_date <= '31-Mar-2018'))
       AND t1.a_c = 'NO'
       AND ( (    t1.s_r IN ('EB', 'PH', 'PT', 'SW')
              AND t1.d_m IN ('DM', 'SW')
              AND t1.c_m = 'SW')
            OR (    t1.s_r IN ('PH', 'PT')
                AND t1.d_m = 'SW'
                AND t1.c_m = 'DM')
            OR (    t1.s_r = 'EB'
                AND t1.d_m = 'SW'
                AND t1.c_m = 'DM'
                AND (t1.b_s, t1.d_w) NOT IN
                        ( ('B', 'A')))
            OR (    t1.s_r = 'SW'
                AND t1.d_m = 'SW'
                AND t1.c_m = 'DM'
                AND t1.d_w NOT IN ('A', 'B')))

MINUS
(SELECT *
   FROM e_t t1
  WHERE ( (t1.a_date >= '16-Mar-2018'
               AND t1.a_date <= '31-Mar-2018')
             OR (t1.r_date >= '16-Mar-2018'
                 AND t1.r_date <= '31-Mar-2018'))
        AND a_c IN ('AC', 'NO')
        AND s_r IN ('EB', 'SW')
        AND d_m IN ('DM', 'SW')
        AND c_m = 'DM'
        AND (o_s,s_w) IN
                (( 'A', 'A'))
        AND r_n LIKE '35RE%'

 UNION ALL

 SELECT *
   FROM e_t t1
  WHERE ( (t1.a_date >= '16-Mar-2018'
               AND t1.a_date <= '31-Mar-2018')
             OR (t1.r_date >= '16-Mar-2018'
                 AND t1.r_date <= '31-Mar-2018'))
        AND a_c = 'NO'
        AND s_r = 'EB'
        AND d_m = 'SW'
        AND c_m = 'DM'
        AND (t1.b_s, t1.d_w) IN
                ( ('A', 'B'))
     )