Упорядочить по количеству подходящих слов - PullRequest
0 голосов
/ 25 октября 2018

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

Вот мой пример данных:

+--------+------------------------------+
| ITM_ID |           ITM_Name           |
+--------+------------------------------+
|      1 | Blue Shirt with white collar |
|      2 | Party dress                  |
|      3 | Black derbies with cap toe   |
|      4 | Sky blue dress               |
+--------+------------------------------+

Если я ищу по словам "blue" и "dress", я хочу получить следующие результаты:

+---+------------------------------+
| 4 | Sky blue dress               |
| 1 | Blue Shirt with white collar |
| 2 | Party dress                  |
+---+------------------------------+

The«Небесно-голубое платье» находится на вершине списка, потому что мы находим оба слова, а не только одно в других строках.

Я понял, как искать слова с помощью CONTAINS:

SELECT ITM_ID, ITM_Name, CHARINDEX(
FROM T_Item_ITM
WHERE CONTAINS(ITM_Name, 'dress OR blue')

Но я не нашел решения для заказа.У тебя есть один ?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Вот другой подход:

DECLARE @Data TABLE (
    Id INT,
    Name VARCHAR(100)
);
INSERT INTO @Data VALUES
    (1, 'Blue Shirt with white collar'),
    (2, 'Party dress'),
    (3, 'Black derbies with cap toe'),
    (4, 'Sky blue dress');

DECLARE @Terms TABLE (
    Value VARCHAR(100)
);
INSERT INTO @Terms VALUES 
    ('dress'),
    ('blue');

WITH TermOccurrences AS (
    SELECT *, (LEN(d.Name) - LEN(REPLACE(d.Name, t.Value, ''))) / LEN(t.Value) AS NumOccurrences
    FROM @Data d
        INNER JOIN @Terms t ON d.[Name] LIKE '%' + t.Value + '%'
), TotalOccurrences AS (
    SELECT Id, SUM(NumOccurrences) AS TotalMatches
    FROM TermOccurrences
    GROUP BY Id
)
SELECT d.Id, d.Name, tot.TotalMatches
FROM TotalOccurrences tot
    INNER JOIN @Data d ON d.Id = tot.Id
ORDER BY tot.TotalMatches DESC

Это проверяет количество вхождений термина путем замены термина пустой строкой и сравнения длины исходного имени с длиной именибез термина.

Я не могу говорить об эффективности этого, но вы можете попробовать другой подход.

0 голосов
/ 25 октября 2018

Вы можете использовать string_split для выделения отдельных слов, а затем group by для их подсчета.

declare @tmp table (ITM_ID int ,  ITM_Name nvarchar(100))
insert @tmp values
     (1 ,'Blue Shirt with white collar')
    ,(2 ,'Party dress')
    ,(3 ,'Black derbies with cap toe')
    ,(4 ,'Sky blue dress')

select a.*
from (
    select t.ITM_ID
        ,count(*) as result_count
    from @tmp t
    cross apply string_split(ITM_Name, ' ') w
    where w.[value] in (
            'blue'
            ,'dress'
            )
    group by ITM_ID
    ) c
inner join @tmp a
    on a.ITM_ID = c.ITM_ID
order by c.result_count desc

Результаты:

enter image description here

Обратите внимание, что если у вас есть дополнительные знаки препинания (запятые, точки с запятой и т. Д.), Вам придется заменить их пробелом перед разбиением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...