Как использовать SQL Server 2016 для сопоставления шаблонов со строками в таблице без использования курсора? - PullRequest
0 голосов
/ 27 февраля 2019

Цвет таблица:

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

Я хочу найти строки для любого из цветов в таблице и вернуть идентификатор найденного цвета.Если не найдено, то у получающейся временной таблицы нет строк.

Например, строки для поиска могут быть

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

Работает, но, похоже, я смогу сделать это без курсора.Как бы я это сделал?

1 Ответ

0 голосов
/ 27 февраля 2019

Вы можете использовать оператор 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

Если у вас есть другая таблица с предложениями, которые вы хотитетест, вы можете сделать соединение между ними, используя то же сравнение, что и условие соединения:

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

Это вернет строку для каждого цвета, найденного в каждом предложении:

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