Показанная вами схема, денормализованная со всеми тегами для каждого видео, вставленного в строку «Теги», плохо разработана для ваших целей - в TSQL нет разумного способа вычислить значимую «общность» между двумя строками в таком формате, и, следовательно, нет разумного способа проверить, какие пары предметов имеют относительно высокую общность и, следовательно, могут считаться «связанными». Если схема неприкасаема, вам придется реализовать определенную пользователем функцию (на C # или другом языке .NET) для этой цели, и даже тогда вам придется более или менее сканировать всю таблицу, поскольку нет разумного способа индекс на такой основе.
Если вы можете изменить схему (с еще двумя таблицами: одна для хранения тегов, а другая для связи «многие-многие» между тегами и видео), у вас могут быть лучшие перспективы; в этом случае некоторые данные о приблизительном количестве (порядка) видео, которое вы ожидаете получить, о количестве (таких же) отдельных тегов в целом и о том, какое количество тегов будет иметь видео, могут позволить разработать и эффективный способ. преследовать ваши цели.
Редактировать: по комментариям, очевидно, схема может быть изменена, хотя все еще не было дано никаких указаний относительно чисел, которые я просил, поэтому соответствующие индексы и с останутся полной загадкой. В любом случае, предположим, что схема выглядит примерно так (каждая таблица может иметь другие столбцы по своему усмотрению, просто добавьте их в запрос; длина VARCHAR также не имеет значения):
CREATE TABLE Videos (VideoID INT PRIMARY KEY,
VideoTitle VARCHAR(80));
CREATE TABLE Tags (TagID INT PRIMARY KEY,
TagText VARCHAR(20));
CREATE TABLE VideosTags (VideoID FOREIGN KEY REFERENCES Videos,
TagID FOREIGN KEY REFERENCES Tags,
PRIMARY KEY (VideoId, TagId));
т.е. просто классический учебник «отношения многие-многие».
Теперь, учитывая название видео, скажем, @MyTitle, названия 5 наиболее «связанных» с ним видео можно легко запросить, например:
WITH MyTags(TagId) AS
(
SELECT VT1.TagID
FROM Videos V1
JOIN VideosTags VT1 ON (V1.VideoID=VT1.VideoID)
WHERE V1.VideoTitle=@MyTitle
)
SELECT TOP(5) V2.VideoTitle, COUNT(*) AS CommonTags
FROM Videos V2
JOIN VideosTags VT2 ON (V2.VideoID=VT2.VideoID)
JOIN MyTags ON (VT2.TagId=MyTags.TagId)
GROUP BY V2.VideoId
ORDER BY CommonTags DESC;