Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Не могу придумать SQL запрос [D6, Access]


TGrey ©   (2004-04-10 11:57:00) 

Дрого времени суток!
Есть три таблицы:

1. ID   //идентификатор слова
  Word //слово
2. ID   //идентификатор документа
  DocL //расположение документа
3. ID   //идентификатор записи
  Word_ID //Идентификатор слова
  Doc_ID  //Идентификатор документа

Не могу придумать запрос, который выдавал бы только те документы, которые имеют все слова указанные в запросе в качестве критерия отбора.


TGrey   (2004-04-13 21:34:00) [1]

Пишет ошибка синтаксиса после в операторе FROM


Johnmen   (2004-04-13 09:20:00) [2]

>TGrey ©   (12.04.04 19:07) [10]

"Не хочет" - это как ? Если ошибки синтаксиса, то какие ?

>kaif ©   (11.04.04 23:39) [9]

Having приведет лишь к незначительному увеличению времени обработки. Вполне возможно, что индекс по W.Word будет использован при его наличии.
А про синтаксис агрегатных ф-ий м.почитать в любом справочнике по SQL, я думаю...


TGrey   (2004-04-12 19:07:00) [3]

Johnmen ваш запрос у меня не хочет работать, в качестве БД я использую Access может там синтаксис немного другой?

Я решил эту задачу с помощью двух запросов, первый возвращает индексы слов:

SELECT WordTable.ID
FROM WordTable
WHERE (((WordTable.Word)="лицо" Or (WordTable.Word)="система" Or (WordTable.Word)="Агафон"));

Второй на основе первого возвращает нужные документы:

SELECT DocumentLinkTable.DocumentLink
FROM [ID words] INNER JOIN (DocumentLinkTable INNER JOIN WordKeysTable ON DocumentLinkTable.ID=WordKeysTable.ID_DocumentLink) ON [ID words].ID=WordKeysTable.ID_NormalWords
GROUP BY DocumentLinkTable.DocumentLink
HAVING (((Count([ID words].ID))>=3));


Появляется новый вопрос, как два запроса объединить в один, то есть первый запихнуть во второй?


kaif   (2004-04-11 23:39:00) [4]

2 Johnmen ©   (11.04.04 21:38) [8]
Я всегда знал, что ты гений SQL!
Но такой вопрос... Это Having не приведет к тупому перебору всех документов, которые содержат хотя бы одно слово (фильтрация на выходе), без всех преимуществ индексов?
Хотя, конечно прикольно.
Я не знал о том, что кроме COUNT(*) существует еще какой-то синтаксис внутри COUNT. :(
А где вообще можно прочитать про COUNT и все варианты его применения? Я обдумывал вариант с использованием COUNT, но меня остановило то, что при повторении 'word1' 3 раза COUNT(*) насчитает те же 3, что и для разных значений.
А вообще решение прекрасное! Мой респект.


Johnmen   (2004-04-11 21:38:00) [5]

>TGrey ©  

Независимо от любых ключей и индексов:

SELECT D.ID FROM D
JOIN M ON M.Doc_ID=D.ID
JOIN W ON W.ID=M.Word_ID
WHERE W.Word IN ('word1','word2','word3')
GROUP BY D.ID
HAVING COUNT(DISTINCT W.Word)>=3

W - таблица слов, D - таблица документов, M - таблица связи


Nikolay M.   (2004-04-11 13:02:00) [6]


> Жестким запросом здесь не обойтись, ИМХО.

Вполне обойтись, имхо.
К запросу [1] нужно дописать условие

...
HAVING 3 = (SELECT count(1) FROM 3_new, 1_new WHERE (2.ID = 3_new.Doc_ID) AND (1_new.ID = 3_new.Word_ID) AND (1_new.Word IN ('One','Two','Three')))

При условии, что в таблице 3 пара (Word_ID, Doc_ID) - первичный ключ, т.е. нет повторений, работать должно.


TGrey   (2004-04-11 11:20:00) [7]

kaif
Попали примо в точку, он самый, поисковик!

Слова из документа нормализуются к словарной форме (таблица 1), а потом связываются с документами (таблица 2), с помощью таблицы 3. Эту работу я уже проделал, осталось поиск организовать, но на поиске застрял. Похоже не получится с помощью одного запроса, буду по другому делать.

Всем спасибо!


kaif   (2004-04-11 00:38:00) [8]

Нужно столько-кратное объединение с таблицей-хранилищем слов, сколько слов одновременно нужно поймать. Например, если требуется одновременное вхождение 5 слов, то придется сделать объединение с таблицей слов 5 раз, каждый раз с новым критерием
Word='One', Word = 'Two', Word = 'Three'. Так что текст запроса придется генерировать автоматически. Жестким запросом здесь не обойтись, ИМХО. К тому же затем придется еще 5 раз объединять с таблицей связи слово-документ и лишь потом однократно с таблицей документов. Итого, для поиска по 5 словам придется объединить 11 таблиц. Имхо, это не есть хорошо...
 Поисковик пишешь? :)


Polevi   (2004-04-10 21:53:00) [9]

ааа, дошло :)
плохо вопрос прочитал сначала


Polevi   (2004-04-10 21:52:00) [10]

я конечно щас не трезв :)) но почему не пойдут ?


Nikolay M.   (2004-04-10 21:10:00) [11]


> Polevi ©   (10.04.04 19:34) [1]

Не-а :)
ВСЕ слова из запроса так не пойдут.


Polevi   (2004-04-10 19:34:00) [12]

SELECT 2.* FROM 2
JOIN 3 ON 3.Doc_Id=2.ID
JOIN 1 ON 1.ID=3.Word_ID
WHERE 1.Word IN ('One','Two','Three')


Наверх

Титульная страница Поиск, карта сайта Написать письмо