在多列中搜索多个包含条件

时间:2017-02-10 16:10:50

标签: sql sql-server

我正在尝试编写一些SQL来查询银行对帐单表,我想填充一列作为'排除'如果5个银行对账单描述栏中的任何一个包含'剩余现金'' CHQ IN AT'或者' ELECTR CHARGE'

我目前的尝试是

select statement_no
      ,bank_text_1
      ,bank_text_2
      ,bank_text_3
      ,bank_text_4
      ,bank_text_5
      ,amount
      ,case
           when bank_text_1 like '%SURPLUS CASH%'
                or bank_text_1 like '%CHQ IN AT%'
                or bank_text_1 like '%ELECTR CHARGE%'
                or bank_text_2 like '%SURPLUS CASH%'
                or bank_text_2 like '%CHQ IN AT%'
                or bank_text_2 like '%ELECTR CHARGE%'
                or bank_text_3 like '%SURPLUS CASH%'
                or bank_text_3 like '%CHQ IN AT%'
                or bank_text_3 like '%ELECTR CHARGE%'
                or bank_text_4 like '%SURPLUS CASH%'
                or bank_text_4 like '%CHQ IN AT%'
                or bank_text_4 like '%ELECTR CHARGE%'
                or bank_text_5 like '%SURPLUS CASH%'
                or bank_text_5 like '%CHQ IN AT%'
                or bank_text_5 like '%ELECTR CHARGE%'
               then 'Exclude'
           else ''
       end as checker;

它非常混乱,看起来效率不高。有没有人有更好的方法建议?

非常感谢

结果数据示例:

Statement_no | bank_text_1 | bank_text_2         | bank_text_3    | bank_text_4 | bank_text_5  | amount | checker
0001         | SURPLUS CASH|                     |                |             |              |125.00  |Exclude
0002         | M THOMAS    |TRAINING FEE         |CHQ IN AT 100217|             |              |470.00  |Exclude
0003         |SWALEC       |Training Centre One  |Abergaveny      |             |Electr Charges|700.00  |Exlcude
0004         |M Thomas     |Training Centre Hire |                |             |              |850.00  |  

4 个答案:

答案 0 :(得分:2)

一个选项是CROSS APPLY

Select statement_no
     , bank_text_1
     , bank_text_2
     , bank_text_3
     , bank_text_4
     , bank_text_5
     , amount  
     , B.Checker
 From  YourTable A
 Cross Apply (Select Checker = case when count(*)>0 then 'Exclude' else '' end
               From ( values (A.bank_text_1)
                    ,(A.bank_text_2)
                    ,(A.bank_text_3)
                    ,(A.bank_text_4)
                    ,(A.bank_text_5) ) C1 (Value)
                Where charindex('SURPLUS CASH',Value)
                     +charindex('CHQ IN AT',Value)
                     +charindex('ELECTR CHARGE',Value) 
                     >0
             ) B

返回

enter image description here

答案 1 :(得分:1)

select *
 , checker = case 
    when charindex('SURPLUS CASH',concat(bank_text_1, bank_text_2, bank_text_3, bank_text_4, bank_text_5))>0
      or charindex('CHQ IN AT',concat(bank_text_1, bank_text_2, bank_text_3, bank_text_4, bank_text_5))>0
      or charindex('ELECTR CHARGE',concat(bank_text_1, bank_text_2, bank_text_3, bank_text_4, bank_text_5))>0
      then 'Exclude' 
    else '' 
    end
from t

结果:http://rextester.com/VBOC27547

+--------------+---------------+-----------------------+------------------+-------------+----------------+--------+---------+
| statement_no |  bank_text_1  |      bank_text_2      |   bank_text_3    | bank_text_4 |  bank_text_5   | amount | checker |
+--------------+---------------+-----------------------+------------------+-------------+----------------+--------+---------+
|         0001 |  SURPLUS CASH |                       |                  |             |                | 125,00 | Exclude |
|         0002 |  M THOMAS     | TRAINING FEE          | CHQ IN AT 100217 |             |                | 470,00 | Exclude |
|         0003 | SWALEC        | Training Centre One   | Abergaveny       |             | Electr Charges | 700,00 | Exclude |
|         0004 | M Thomas      | Training Centre Hire  |                  |             |                | 850,00 |         |
+--------------+---------------+-----------------------+------------------+-------------+----------------+--------+---------+

与John Cappellet的超过1,000,000行的答案相比,我测试了它的表现,我认为它们具有可比性。

我个人的偏好是约翰的回答,使用cross apply()

在下面的集合中,每个集合中的第一个查询使用charindex(...,concat(..),第二个查询是约翰的cross apply()版本。

此实例的硬件规格相当薄弱,因此您的里程会有所不同。

-----------------------

(1000000 row(s) affected)
Table 't'. Scan count 1, logical reads 8153, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 3010 ms,  elapsed time = 8750 ms.

(1000000 row(s) affected)
Table 't'. Scan count 1, logical reads 8153, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 5585 ms,  elapsed time = 8725 ms.

-----------------------

(1000000 row(s) affected)
Table 't'. Scan count 1, logical reads 8153, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 3307 ms,  elapsed time = 8685 ms.

(1000000 row(s) affected)
Table 't'. Scan count 1, logical reads 8153, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 5663 ms,  elapsed time = 8913 ms.

-----------------------

(1000000 row(s) affected)
Table 't'. Scan count 1, logical reads 8153, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 3073 ms,  elapsed time = 8414 ms.

(1000000 row(s) affected)
Table 't'. Scan count 1, logical reads 8153, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 5647 ms,  elapsed time = 9049 ms.

-------------------

(1000000 row(s) affected)
Table 't'. Scan count 1, logical reads 8153, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 3011 ms,  elapsed time = 8706 ms.

(1000000 row(s) affected)
Table 't'. Scan count 1, logical reads 8153, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 5491 ms,  elapsed time = 8704 ms.

-----------------------

答案 2 :(得分:0)

这看起来有点整洁,但它应该表现得相同:

SELECT statement_no, 
       bank_text_1, bank_text_2, bank_text_3, bank_text_4, bank_text_5,
       amount,
       IIF(x.IsChecked = 1, 'Exclude', '')
FROM mytable
CROSS APPLY (
   SELECT SUM(CASE 
                 WHEN (t.v LIKE '%SURPLUS CASH%') OR 
                      (t.v LIKE '%CHQ IN AT%') OR 
                      (t.v LIKE '%ELECTR CHARGE%') 
                   THEN 1 
                 ELSE 0 
              END) AS IsChecked
   FROM 
   (      
      VALUES (bank_text_1), (bank_text_2), (bank_text_3), (bank_text_4), (bank_text_5)
   ) AS t(v) 
) AS x

答案 3 :(得分:0)

你应该尝试:

select statement_no
      ,bank_text_1
      ,bank_text_2
      ,bank_text_3
      ,bank_text_4
      ,bank_text_5
      ,amount
      ,case
           when q.item is not null
               then 'Exclude'
           else ''
       end as checker
from queries 
left join
(
       select '%CHQ IN AT%' item union
       select '%ELECTR CHARGE%' item union    
       select '%SURPLUS CASH%' item
) q on bank_text_1 like item or 
       bank_text_2 like item or
       bank_text_3 like item or
       bank_text_4 like item or
       bank_text_5 like item

我不确定表现,但在我看来,加入比交叉申请更轻。如果你能分享我感兴趣的基准。