我需要根据nvarchar(2000)列中的某些文本匹配来过滤掉记录。
我需要的记录超过条件
所有条件可能来自另一张桌子。
例如,假设我的TableA
包含以下记录:
ID RecordNote
1 1:15&2:30&3:40
2 2:50&1:40&3:50
3 2:60&1:30&4:50
4 3:50&1:40&2:60
5 7:50&2:40&3:60
和TableB
:
PatternID Pattern
1 3:50
2 2:60
我想从TablA
中选择所有记录,其中RecordNotes的值为3:50& 2:60
类似这样的事情
SELECT *
From TableA
Where RecordNotes LIKE '%3:50%'
AND RecordNotes LIKE '%2:60%'
最好的方法是什么?
答案 0 :(得分:0)
在SQL Server 2016+中,您可以使用string_split()
。
在2016年之前的SQL Server中,使用由Jeff Moden在common table expression中使用cross apply()
的CSV Splitter表值函数:
create table t (ID int,RecordNote varchar(32));
insert into t values
(1,'1:15&2:30&3:40')
,(2,'2:50&1:40&3:50')
,(3,'2:60&1:30&4:50')
,(4,'3:50&1:40&2:60')
,(5,'7:50&2:40&3:60');
create table p (patternId int, Pattern varchar(32));
insert into p values (1,'3:50'),(2,'2:60');
;with cte as (
select
t.Id
, RecordNote = s.Item
, RecordNoteMatches = count(*) over (partition by t.Id)
from t
cross apply dbo.delimitedsplit8K(t.RecordNote,'&') s
inner join p
on p.Pattern = s.Item
)
select *
from cte
where RecordNoteMatches = (select count(*) from p);
rextester 演示:http://rextester.com/KKTR95367
返回:
+----+------------+-------------------+
| Id | RecordNote | RecordNoteMatches |
+----+------------+-------------------+
| 4 | 3:50 | 2 |
| 4 | 2:60 | 2 |
+----+------------+-------------------+
拆分字符串参考:
string_split()
in SQL Server 2016 : Follow-Up #1 - Aaron Bertrand 如果您只想要匹配的Id
,那么您可以将查询简化为:
;with cte as (
select
t.Id
, RecordNoteMatches = count(*)
from t
cross apply dbo.delimitedsplit8K(t.RecordNote,'&') s
inner join p
on p.Pattern = s.Item
group by t.Id
)
select *
from cte
where RecordNoteMatches = (select count(*) from p);
rextester 演示:http://rextester.com/RDZWF26107
返回:
+----+-------------------+
| Id | RecordNoteMatches |
+----+-------------------+
| 4 | 2 |
+----+-------------------+
答案 1 :(得分:0)
请尝试使用以下代码:
CREATE TABLE TableA (ID INT,RecordNote NVARCHAR(2000))
INSERT INTO TableA VALUES
(1,'1:15&2:30&3:40'),
(2,'2:50&1:40&3:50'),
(3,'2:60&1:30&4:50'),
(4,'3:50&1:40&2:60'),
(5,'7:50&2:40&3:60')
CREATE TABLE TableB (PatternID INT,Pattern NVARCHAR(2000))
INSERT INTO TableB VALUES
(1,'3:50'),
(2,'2:60')
DECLARE @NUMBERS AS NVARCHAR(MAX)
SELECT @NUMBERS = COALESCE(@NUMBERS + '%'') AND A.RecordNote LIKE (''%', '') + B.Pattern FROM TableB B
DECLARE @QUERY NVARCHAR(MAX)
SET @QUERY =
'SELECT DISTINCT ID,RecordNote FROM TableA A INNER JOIN TableB B
ON A.RecordNote LIKE (''%'+@NUMBERS+'%'')'
EXEC (@QUERY)
答案 2 :(得分:0)
WITH CTE AS (
SELECT *, STUFF(RECORDNOTE, 5, 5, '') AS Data
FROM TableA)
SELECT ID, RecordNote FROM CTE WHERE Data = '3:50&2:60'
答案 3 :(得分:0)
;WITH cte1(ID,RecordNote)
AS
(
SELECT 1,'1:15&2:30&3:40' UNION ALL
SELECT 2,'2:50&1:40&3:50' UNION ALL
SELECT 3,'2:60&1:30&4:50' UNION ALL
SELECT 4,'3:50&1:40&2:60' UNION ALL
SELECT 5,'7:50&2:40&3:60'
)
,cte2( PatternID,Pattern)
AS
(
SELECT 1,'3:50' union all
SELECT 2,'2:60'
)
SELECT cte2.Pattern,cte1.ID,cte1.RecordNote
FROM cte2
CROSS JOIN cte1
WHERE CHARINDEX(Pattern, Right(RecordNote, CHARINDEX('&', REVERSE(RecordNote)))) > 0