Форум: "Базы";
Текущий архив: 2003.06.09;
Скачать: [xml.tar.bz2];
ВнизПожалуйста, помогите составить запрос... Найти похожие ветки
← →
Snake (2003-05-19 14:00) [0]Есть 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")
А вот как для обязательного попадания всех слов - ума не приложу... Это я поиск по сайту пытаюсь набросать, если получится - в Сети выложу программу индексации и сам поиск ;)
← →
NickBat (2003-05-19 14:35) [1]> WHERE (Words.aWord Like "слово1") Or (Words.aWord Like "Слово2")
> А вот как для обязательного попадания всех слов - ума не приложу...
Хм... Вместо or поставь and
← →
Snake (2003-05-19 15:09) [2]Я тоже так сначала подумал. Не ест - в это случае получается что поле aWord для данной записи должно быть одновременно и тем и другим словом :(
← →
Соловьев (2003-05-19 15:17) [3]
> Snake © (19.05.03 15:09)
and конечно
← →
Danilka (2003-05-19 15:25) [4]не уверен на счет аццеса, но в нормальном скуль-синтаксисе это выглядит так:
(Words.aWord Like " %слово1 %") and (Words.aWord Like " %Слово2 %")
да, и еще, у тебя будет поиск с учетом регистра, то есть "слово2" уже не удовлетворяет условиям.
← →
Snake (2003-05-20 05:28) [5]Да не, с регистром все в порядке, в Акцесе таких проблем у меня еще не возникало. Я и так ставлю процент... Но не хавает он слово 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 привязан, а это не есть хорошо.
← →
Соловьев (2003-05-20 09:42) [6]
> 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 15:10) [7]Там ASP-шный код стоит, который, собственно все это и проставляет - и слова и их количество, тоже в цикле. А с Union... Это идея. Спасибо, надо попробовать.
← →
sniknik (2003-05-20 15:37) [8]Like "%словоN%" индексов не использует и будет сканить таблицу столько сколько union вставиш. т.е. быстро не будет.
может так пойдет
WHERE (aWord Like "%слово1%слово2%")
правда будет важен порядок, а нужно любой..?, наверное это тот случай когда свой цикл будет быстрее всего работать. (во всяком случае за один проход)
← →
Соловьев (2003-05-20 15:40) [9]
> Snake © (20.05.03 15:10)
> sniknik © (20.05.03 15:37)
или onFilterRecord попробовать.
← →
Sandman25 (2003-05-20 16:12) [10]На 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 проблемой быть вроде не должно.
← →
sniknik (2003-05-20 16:47) [11]еще вариант, проверь не быстрее ли будет.
.... WHERE InStr(aWord, "слово1")>0 AND InStr(aWord, "слово2")>0
для Access, порядок неважен, однопроходной, на скорость смотри в реальной базе.
← →
Snake (2003-05-21 05:35) [12]Спасибо, Вам, люди!!! Кажись, заработало! Правда вот почему-то первый запрос Sandman25 © выдает пустой результат, не могу понять почему, а второй работает.
← →
Sandman25 (2003-05-21 10:12) [13]Извиняюсь, я забыл в первом запросе добавить
AND wp3.word_id = w3.word_id
но это могло привести только к дублированию результата, а не к пустому. Первый запрос должен работать быстрее, чем второй (по крайней мере, для не очень продвинутых оптимизаторов), так что можем попытаться исправить мою ошибку.
Как Вы перевели первый запрос на Access?
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.06.09;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.009 c