SQL选择一列中匹配多个条件的所有行

时间:2017-04-09 12:46:23

标签: sql-server tsql

我需要根据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%' 

最好的方法是什么?

4 个答案:

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

拆分字符串参考:

如果您只想要匹配的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