我正在尝试编写一些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 |
答案 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
返回
答案 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
我不确定表现,但在我看来,加入比交叉申请更轻。如果你能分享我感兴趣的基准。