![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Пожалуйста, помогите составить запрос... [Access]
Snake © (2003-05-19 14:00:00)Есть 2 таблицы: Страницы (Pages: ID, Title), Слова (Words: ID, aWord) и связывающая их - Word_Page: ID, Page_ID, Word_ID. Пользователь вводит запрос из набора слов: надо выбрать страницы, которые содержат все введенные слова. Для любого попадания из слов сделал:
SELECT DISTINCT Pages.*
FROM (Pages INNER JOIN Word_Page ON Pages.ID=Word_Page.Page_ID) INNER JOIN Words ON Word_Page.Word_ID=Words.ID
WHERE (Words.aWord Like "слово1") Or (Words.aWord Like "Слово2")
А вот как для обязательного попадания всех слов - ума не приложу... Это я поиск по сайту пытаюсь набросать, если получится - в Сети выложу программу индексации и сам поиск ;)
Sandman25 (2003-05-21 10:12:00) [1]Извиняюсь, я забыл в первом запросе добавить
AND wp3.word_id = w3.word_id
но это могло привести только к дублированию результата, а не к пустому. Первый запрос должен работать быстрее, чем второй (по крайней мере, для не очень продвинутых оптимизаторов), так что можем попытаться исправить мою ошибку.
Как Вы перевели первый запрос на Access?
Snake (2003-05-21 05:35:00) [2]Спасибо, Вам, люди!!! Кажись, заработало! Правда вот почему-то первый запрос Sandman25 © выдает пустой результат, не могу понять почему, а второй работает.
sniknik (2003-05-20 16:47:00) [3]еще вариант, проверь не быстрее ли будет.
.... WHERE InStr(aWord, "слово1")>0 AND InStr(aWord, "слово2")>0
для Access, порядок неважен, однопроходной, на скорость смотри в реальной базе.
Sandman25 (2003-05-20 16:12:00) [4]На Informix SQL это можно сделать так:
SELECT p.*
FROM pages p,
word_page wp1,
words w1,
word_page wp2,
words w2,
word_page wp3,
words w3
WHERE w1.aWord matches "*word1*"
AND wp1.word_id = w1.word_id
AND w2.aWord matches "*word2*"
AND wp2.word_id = w2.word_id
AND w3.aWord matches "*word3*"
AND p.page_id = wp1.page_id
AND p.page_id = wp2.page_id
AND p.page_id = wp3.page_id
или так:
SELECT p.*
FROM pages p
WHERE
EXISTS
(SELECT wp.*
FROM word_page wp,
words w
WHERE w.aWord matches "*word1*"
AND wp.word_id = w.word_id
AND wp.page_id = p.page_id
)
AND EXISTS
(SELECT wp.*
FROM word_page wp,
words w
WHERE w.aWord matches "*word2*"
AND wp.word_id = w.word_id
AND wp.page_id = p.page_id
)
AND EXISTS
(SELECT wp.*
FROM word_page wp,
words w
WHERE w.aWord matches "*word2*"
AND wp.word_id = w.word_id
AND wp.page_id = p.page_id
)
Надеюсь, идеи понятны. Перевести на другой диалект SQL проблемой быть вроде не должно.
Соловьев (2003-05-20 15:40:00) [5]
> Snake © (20.05.03 15:10)
> sniknik © (20.05.03 15:37)
или onFilterRecord попробовать.
sniknik (2003-05-20 15:37:00) [6]Like "%словоN%" индексов не использует и будет сканить таблицу столько сколько union вставиш. т.е. быстро не будет.
может так пойдет
WHERE (aWord Like "%слово1%слово2%")
правда будет важен порядок, а нужно любой..?, наверное это тот случай когда свой цикл будет быстрее всего работать. (во всяком случае за один проход)
Snake (2003-05-20 15:10:00) [7]Там ASP-шный код стоит, который, собственно все это и проставляет - и слова и их количество, тоже в цикле. А с Union... Это идея. Спасибо, надо попробовать.
Соловьев (2003-05-20 09:42:00) [8]
> Snake © (20.05.03 05:28)
интересно, а если введут 3 слова, 4, 5... Что тогда? Как у тебя тогда будет выглядеть запрос? попробуй через Union связать сгенеренные в цыкле запросы
SELECT Pages.*
FROM Pages
JOIN Word_Page ON Pages.ID=Word_Page.Page_ID
WHERE (Words.aWord Like "%словоN%")
union
....
Snake (2003-05-20 05:28:00) [9]Да не, с регистром все в порядке, в Акцесе таких проблем у меня еще не возникало. Я и так ставлю процент... Но не хавает он слово and, и все тут. Не верите - можете проверить. Я вот тут накатал запрос, но, извините за выражение, "через задницу":
SELECT DISTINCT Pages.Title
FROM Pages INNER JOIN Word_Page ON Pages.ID=Word_Page.Page_ID
WHERE Word_Page.Word_ID IN (SELECT ID FROM Words WHERE (aWord Like "%слово1%") or (Words.aWord Like "%слово2%"))
GROUP BY Pages.Title, Word_Page.Page_ID
HAVING Count(Word_Page.Page_ID)=2
Работает он очень медленно, и главное, если в запросе будет 2 одинаковых слова - он ничего не выбросит, да и вообще работает немного глючно, потому что к Count привязан, а это не есть хорошо.
Danilka (2003-05-19 15:25:00) [10]не уверен на счет аццеса, но в нормальном скуль-синтаксисе это выглядит так:
(Words.aWord Like " %слово1 %") and(Words.aWord Like " %Слово2 %")
да, и еще, у тебя будет поиск с учетом регистра, то есть "слово2" уже не удовлетворяет условиям.
Соловьев (2003-05-19 15:17:00) [11]
> Snake © (19.05.03 15:09)
andконечно
Snake (2003-05-19 15:09:00) [12]Я тоже так сначала подумал. Не ест - в это случае получается что поле aWord для данной записи должно быть одновременно и тем и другим словом :(
NickBat (2003-05-19 14:35:00) [13]> WHERE (Words.aWord Like "слово1") Or (Words.aWord Like "Слово2")
> А вот как для обязательного попадания всех слов - ума не приложу...
Хм... Вместо or поставь and