2017-04-09 490 views
0

我需要根据nvarchar(2000)列中的某些文本匹配过滤出记录。SQL选择一列中匹配多个条件的所有行

我需要应用多个条件

所有条件可能来自另一个表的记录。 例如,假设我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%' 

这样做的最好方法是什么?

+1

你的根本问题是你错误地表示了数据。您不应该将事物列表存储为字符串。你应该为每个TableA.Id和Pattern创建另一个表。 –

+0

最初的模式是在一列'3:50&1:-1&2:60',我想使用此模式搜索,但有一些条件 1-使用ID删除-1,所以我的模式将是'3:50&2:60 ' 2-删除&因为reocrdNotes不存储& 所以我使用拆分字符串函数来获取表格中的模式 –

回答

0

在SQL Server 2016+中,您可以使用string_split()

在SQL Server预-2016,在common table expression使用由杰夫MODEN一个CSV分路器表值函数cross apply()

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 | 
+----+------------+-------------------+ 

拆分字符串参考:


如果你只是想在Id S上的比赛,那么你就可以简化查询:

;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 | 
+----+-------------------+ 
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 (''%'[email protected]+'%'')' 

    EXEC (@QUERY) 
0
WITH CTE AS (
SELECT *, STUFF(RECORDNOTE, 5, 5, '') AS Data 
FROM TableA) 

SELECT ID, RecordNote FROM CTE WHERE Data = '3:50&2:60' 
+0

尝试给您的答案提供更多上下文。它可能会解决这个问题,但为什么这个工作,而问题作者版本不是? – Adam

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 
相关问题