2017-04-09 214 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 
相關問題