Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.06.09;
Скачать: CL | DM;

Вниз

Пожалуйста, помогите составить запрос...   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.025 c
3-26337
kingdom2000
2003-05-16 19:07
2003.06.09
TDBGridEh и GetEditText(X, Y)


1-26519
anod
2003-05-30 05:15
2003.06.09
Как создать новый класс?


14-26757
VitGun
2003-05-22 21:07
2003.06.09
DBGrid + Tree


14-26669
Maximator Vetera
2003-05-22 14:17
2003.06.09
Самоорганизацию, самоподобие и избыточность в классы!


1-26602
Dimedrol
2003-05-28 15:12
2003.06.09
Access violation ... in module rtl60.bpl