如何在不使用游标的情况下使用 SQL Server 2016 对 table 中的字符串进行模式匹配?

How do I use SQL Server 2016 to pattern match against strings in a table without using a cursor?

颜色 table:

  ID    Color
+-----+---------+
|  1  | Red     |
+-----+---------+
|  2  | Blue    |
+-----+---------+
|  3  | Green   |
+-----+---------+

我想在 table 和 return 找到的颜色 ID 中搜索任何颜色的字符串。如果未找到,则生成的临时文件 table 没有行。

例如,要搜索的字符串可能是

'Today we have the blue plate special'
'The light is red'
'That is lemon yellow' -- this won't be found

我可以使用光标:

DECLARE @index INT
DECLARE @str nchar(50) = 'Today we have the blue plate special'

DECLARE @colors TABLE
                (
                    id INT,
                    color NCHAR(20)
                )

DECLARE Color_Cursor CURSOR FOR  
    SELECT Id, Color 
    FROM ColorTable;

DECLARE @colorId INT
DECLARE @matchColor nchar (10)

OPEN Color_Cursor;  

FETCH NEXT FROM Color_Cursor into @colorId, @matchColor;  

WHILE @@FETCH_STATUS = 0  
BEGIN  
    SELECT 
        @index = CHARINDEX(LTRIM(RTRIM(@matchColor)), 
        @str COLLATE Latin1_General_CI_AS) 

    IF (@index <> 0)
    BEGIN
        INSERT INTO @colors (id, color) 
            (SELECT @colorId, @matchColor)
    END

    FETCH NEXT FROM Color_Cursor into @colorId, @matchColor; 
END;  

CLOSE Color_Cursor;  
DEALLOCATE Color_Cursor;  

SELECT * FROM @colors

结果是:

+-----+---------+
|  2  | Blue    |
+-----+---------+

有效,但似乎我应该能够在没有光标的情况下执行此操作。我该怎么做?

您可以使用 LIKE 运算符并指定不区分大小写的排序规则:

WITH ColorTable(ID, Color) As
(
    SELECT 1, 'Red' Union
    SELECT 2, 'Blue' union
    SELECT 3, 'Green'
)
SELECT 
    *
FROM
    ColorTable 
WHERE 
    'Today we have the blue plate special' LIKE '%' + Color + '%' COLLATE Latin1_General_CI_AS

结果:

ID | Color
---+------
 2 | Blue

如果您有另一个 table 包含要测试的句子,您可以使用与连接条件相同的比较在两者之间进行连接:

WITH ColorTable(ID, Color) As
(
    SELECT 1, 'Red' Union
    SELECT 2, 'Blue' union
    SELECT 3, 'Green'
)
, Sentences(Sentence) AS
(
    SELECT 'Today we have the blue plate special' UNION
    SELECT 'The light is red' UNION
    SELECT 'That is lemon yellow'  UNION
    SELECT 'A red fox jumped over a green bucket'
)
SELECT 
    *
FROM
    Sentences s
JOIN
    ColorTable c
    ON
    s.Sentence LIKE '%' + c.Color + '%' COLLATE Latin1_General_CI_AS

这将为每个句子中找到的每种颜色 return 一行:

Sentence                             | ID | Color
-------------------------------------+----+------
The light is red                     |  1 | Red
Today we have the blue plate special |  2 | Blue
A red fox jumped over a green bucket |  1 | Red
A red fox jumped over a green bucket |  3 | Green