Допустим, у вас есть таблица Photo и таблица Word, и у вас есть отношение многие ко многим, используя дополнительную таблицу WordToPhoto:
DECLARE @Photo TABLE
(ID INT, Name VARCHAR(20), Title VARCHAR(50), Description VARCHAR(200))
INSERT INTO @Photo
SELECT 1, 'mountain.jpg', 'Mountain trip', 'Mountain trip'
UNION
SELECT 2, 'beach.jpg', 'On the beach', 'On the beach'
UNION
SELECT 3, 'garden.jpg', 'Garden', 'Garden'
DECLARE @Word TABLE(ID INT, Value VARCHAR(20))
INSERT INTO @Word
SELECT 1, 'dog'
UNION
SELECT 2, 'flowers'
UNION
SELECT 3, 'sea'
UNION
SELECT 4, 'moon'
UNION
SELECT 5, 'mountain'
UNION
SELECT 6, 'seashell'
UNION
SELECT 7, 'shell'
UNION
SELECT 8, 'concert'
DECLARE @WordToPhoto TABLE(ID INT, PhotoID INT, WordID INT)
INSERT INTO @WordToPhoto
SELECT 1, 1, 2
UNION
SELECT 2, 1, 4
UNION
SELECT 3, 2, 1
UNION
SELECT 4, 2, 3
UNION
SELECT 5, 2, 6
UNION
SELECT 6, 3, 1
UNION
SELECT 7, 3, 2
И вы делаете поисковый запрос для ключевых слов "собачка" и "цветок":
DECLARE @Words TABLE (Word VARCHAR(20))
INSERT INTO @Words
SELECT 'doggy' UNION
SELECT 'flower'
Если у вас есть поиск с несколькими ключевыми словами, то вам может понадобиться система рейтинга. Я предлагаю суммировать баллы за каждую фотографию. Точка будет рассчитываться с использованием этого алгоритма:
If Photo Keyword is the same as Search Keyword then 1
(dog = dog)
Else If Photo Keyword is a Search Keyword with postfix then 0.75
(dog LIKE doggy)
Else If Search Keyword is a Photo Keyword with postfix then 0.75
(doggy LIKE dog)
Else If Photo Keyword is a Search Keyword with prefix then 0.5
(dog LIKE bulldog)
Else If Search Keyword is a Photo Keyword with prefix then 0.5
(hotdog LIKE dog)
Else If Photo Keyword is a Search Keyword with prefix and postfix then 0.25
(dog LIKE Snoopdogg)
Else If Search Keyword is a Photo Keyword with prefix and postfix then 0.25
(overdogged LIKE dog)
Точечные коэффициенты могут быть другими, это всего лишь пример.
Реализация:
SELECT R.Rating, P.* FROM @Photo P
INNER JOIN
(
SELECT PhotoID, SUM(W.Point) AS Rating
FROM @WordToPhoto WTP
INNER JOIN (
SELECT W.ID,
CASE
WHEN (LOWER(WS.Word) = LOWER(W.Value)) THEN 1
WHEN (LOWER(WS.Word) LIKE LOWER(W.Value)+'%')
OR (LOWER(W.Value) LIKE LOWER(WS.Word)+'%') THEN 0.75
WHEN (LOWER(WS.Word) LIKE '%'+LOWER(W.Value))
OR (LOWER(W.Value) LIKE '%'+LOWER(WS.Word)) THEN 0.5
ELSE 0.25
END AS Point
FROM @Word W
INNER JOIN @Words WS ON LOWER(WS.Word) LIKE '%'+LOWER(W.Value)+'%'
OR LOWER(W.Value) LIKE '%'+LOWER(WS.Word)+'%'
) AS W ON W.ID = WTP.WordID
GROUP BY PhotoID
) AS R ON P.ID = R.PhotoID
ORDER BY R.Rating DESC
Результат:
Rating ID Name Title Description
1.50 3 garden.jpg Garden Garden
0.75 1 mountain.jpg Mountain trip Mountain trip
0.75 2 beach.jpg On the beach On the beach