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

Вниз

Не могу придумать SQL запрос   Найти похожие ветки 

 
TGrey ©   (2004-04-10 11:57) [0]

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

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

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


 
Polevi ©   (2004-04-10 19:34) [1]

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")


 
Nikolay M. ©   (2004-04-10 21:10) [2]


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

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


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

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


 
Polevi ©   (2004-04-10 21:53) [4]

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


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

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


 
TGrey ©   (2004-04-11 11:20) [6]

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

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

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


 
Nikolay M. ©   (2004-04-11 13:02) [7]


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

Вполне обойтись, имхо.
К запросу [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) - первичный ключ, т.е. нет повторений, работать должно.


 
Johnmen ©   (2004-04-11 21:38) [8]

>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 - таблица связи


 
kaif ©   (2004-04-11 23:39) [9]

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


 
TGrey ©   (2004-04-12 19:07) [10]

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));


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


 
Johnmen ©   (2004-04-13 09:20) [11]

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

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

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

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


 
TGrey ©   (2004-04-13 21:34) [12]

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



Страницы: 1 вся ветка

Текущий архив: 2004.04.11;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.048 c
8-1076358343
Graff
2004-02-09 23:25
2004.04.11
Помогите с перерисовкой PaintBox и Image.


11-1060887040
KreZ0n
2003-08-14 22:50
2004.04.11
Расширения файлов


1-1079920174
YT
2004-03-22 04:49
2004.04.11
Использование TStrnLst.Objects


3-1081751096
_sulent
2004-04-12 10:24
2004.04.11
SQL Server


14-1079610123
nikitos
2004-03-18 14:42
2004.04.11
Где найти заказчика?