如何从下面过滤特定记录?

时间:2018-12-03 06:53:06

标签: sql sql-server tsql sql-server-2008

我有一个表( Mytable ),其值如下所示:

CustNo Audit   History   Inputter Authoriser

 1     CHANGE  CURRENT    XYZ      XYZ
 2     CHANGE  BEFORE     XYZ      XYZ
 2     CHANGE  CURRENT    TOM      TOM
 3     ADD     NEW        TOM      TOM

如果Inputter和Authoriser的值分别为“ XYZ”,Audit ='CHANGE'和History ='CURRENT',则只需要过滤记录,但是对于Inputter和Authoriser,它的审计和历史记录可以分别为CHANGE和BEFORE具有值“ XYZ”和其他记录

我的预期输出如下:

CustNo Audit   History   Inputter Authoriser

 2     CHANGE  BEFORE     XYZ      XYZ
 2     CHANGE  CURRENT    TOM      TOM
 3     ADD     NEW        TOM      TOM

我使用了以下内容,但没有得到我所例外的内容;

select * from Mytable
where  (Inputter != 'XYZ' and Authoriser != 'XYZ' and Audit != 'CHANGE' and History != 'CURRENT' )

有人可以纠正我,如何实现我的预期输出。预先感谢。

**请原谅我的要求,以下是新的例外; **

现在我的现有需求中需要添加另一种方案, 下面是表格记录;

CustNo Audit   History   Inputter Authoriser

 1     ADD     NEW        Sasha    Sasha      
 1     CHANGE  BEOFRE     MAX      MAX
 1     CHANGE  CURRENT    XYZ      XYZ
 2     CHANGE  BEFORE     XYZ      XYZ
 2     CHANGE  CURRENT    TOM      TOM
 3     ADD     NEW        TOM      TOM
 3     CHANGE  CURRENT    MAX      MAX

如果任何输入者和授权者的审计工作为'XYZ',历史记录的审计工作为'CHANGE''CURRENT',则应删除该记录(这是现有工作)以及任何相同的记录custNo在表中。

例如,这里custNo = 1具有'XYZ''CHANGE''CURRENT',  因此应与之删除;

custNo = 1'CHANGE'的{​​{1}}和'BEOFRE'
'MAX'custNo = 1'ADD''NEW'

换句话说,请删除在“输入方和授权方”字段中都有'Sasha'且在“审计和历史记录”字段中有'XYZ''CHANGE'的相同CustNo 的任何出现),无论审计和历史记录如何,即使在输入者和授权者字段中没有'CURRENT'也是如此。

新的预期输出:

'XYZ'

4 个答案:

答案 0 :(得分:1)

代替AND在条件中使用OR

DEMO

select * from Mytable
where  (Inputter != 'XYZ' or Authoriser != 'XYZ' or Audit != 'CHANGE' or History != 'CURRENT' )

输出:

Audit   History  Inputter   Authoriser
Change  before   xyz          xyz
Change  CURRENT  TOM          TOM
ADD       NEW    TOM          TOM

答案 1 :(得分:1)

您需要执行的一个操作如下。使用CASE语句过滤出符合特定条件的xyz记录

select * 
  from Mytable a
 where  CASE WHEN a.Inputter=a.Authoriser AND a.Inputter='XYZ' AND a.Audit='CHANGE' AND a.History ='CURRENT'THEN
                  NULL
             ELSE a.History
         END = a.History

答案 2 :(得分:1)

您可以使用minus设置运算符:

with t( CustNo, Audit, History, Inputter, Authoriser ) as
(
 select 1,'CHANGE','CURRENT','XYZ','XYZ'  union all
 select 2,'CHANGE','BEFORE','XYZ','XYZ'  union all
 select 2,'CHANGE','CURRENT','TOM','TOM'  union all
 select 3,'ADD','NEW','TOM','TOM' 
)
select * from t
minus
select *
  from t
 where Audit = 'CHANGE'
   and History = 'CURRENT'
   and Authoriser = 'XYZ';

CustNo  Audit   History   Inputter  Authoriser
------- ------  --------  --------  ----------
  2     CHANGE  BEFORE     XYZ      XYZ
  2     CHANGE  CURRENT    TOM      TOM
  3     ADD     NEW        TOM      TOM

not in也可以使用:

select * 
  from t
where ( Audit, History, Authoriser ) not in 
      (
        select Audit, History, Authoriser
          from t
         where Audit = 'CHANGE'
           and History = 'CURRENT'
           and Authoriser = 'XYZ' );

答案 3 :(得分:1)

最简单的方法是使用not

SELECT CustNo, Audit, History, Inputter, Authoriser
FROM MyTable
WHERE NOT (
    Inputter = 'XYZ' 
    AND Authoriser = 'XYZ' 
    AND Audit = 'CHANGE' 
    AND History = 'CURRENT'
)

更新:对于新要求,不存在就很容易做到:

SELECT CustNo, Audit, History, Inputter, Authoriser
FROM MyTable t0
WHERE NOT EXISTS
(
    SELECT 1
    FROM MyTable t1
    WHERE t1.CustNo = t0.CustNo
    AND Inputter = 'XYZ' 
    AND Authoriser = 'XYZ' 
    AND Audit = 'CHANGE' 
    AND History = 'CURRENT'
)