【问题标题】:How to filter specific records from the below?如何从下面过滤特定记录?
【发布时间】:2018-12-03 06:53:06
【问题描述】:

我有一个表 (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,它可以分别将 Audit 和 History 作为 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

如果任何 Inputter 和 Authoriser 具有 'XYZ' 和 Audit 并且历史具有 'CHANGE''CURRENT',则应删除该记录(这是现有的工作)以及表中出现的任何相同custNo

例如,这里custNo = 1'XYZ''CHANGE' & 'CURRENT', 所以这应该与;

custNo = 1'CHANGE''BEOFRE' 用于'MAX'
custNo = 1'ADD''NEW' 用于'Sasha'

换句话说 - 删除任何出现的相同 CustNo (在 Inputter 和 Authoriser 字段中都有 'XYZ',在 Audit 和 History 字段中分别有 'CHANGE''CURRENT'无论任何审计和历史记录如何,即使该客户在输入者和授权者字段中没有 'XYZ'

新的预期输出:

CustNo Audit   History   Inputter Authoriser

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

【问题讨论】:

  • 为什么在您的预期输出中有CustNo = 3 而不是CustNo = 1
  • 这就是我需要过滤的内容,即CustNo =1,因为CustNo =1 的审计和历史记录分别为 CHANGE 和 CURRENT。换句话说,对于 Inputter 和 Authoriser 的任何审计和历史记录为 CHANGE 和 CURRENT 的 custNo 都不应报告,其他任何情况都应报告。
  • 你的逻辑我不清楚,你需要更好地在这个网站上发布明确的问题。

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


【解决方案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'
)

【讨论】:

  • 感谢@Zohar,我的要求略有变化,请注意。
  • 非常感谢@Zohar。您的解决方案满足我的要求。
【解决方案2】:

您有一个选择是执行以下操作。使用 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

【讨论】:

  • 如果History 是可空列,则该语句不会返回任何为空的记录。
  • 感谢@George,我的要求略有变化,请注意。
  • @Mar1009,你碰巧有一个 audit_id 来决定所有“之前”的记录
  • @ZoharPeled。你是对的。我只是假设该字段不为空
  • 没有@GeorgeJoseph 没有audit_id 来决定所有before的记录
【解决方案3】:

在条件下使用OR 代替AND

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

【讨论】:

  • 感谢@fa06,我的要求略有变化,请注意。
【解决方案4】:

您可以使用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' );

【讨论】:

  • 感谢@Barbaros,我的要求略有变化,请注意。
猜你喜欢
  • 2015-05-21
  • 2020-10-12
  • 2016-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-27
相关资源
最近更新 更多