Форум: "Базы";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
ВнизНе могу придумать SQL запрос Найти похожие ветки
← →
TGrey © (2004-04-10 11:57) [0]Дрого времени суток!
Есть три таблицы:
1. ID //идентификатор слова
Word //слово
2. ID //идентификатор документа
DocL //расположение документа
3. ID //идентификатор записи
Word_ID //Идентификатор слова
Doc_ID //Идентификатор документа
Не могу придумать запрос, который выдавал бы только те документы, которые имеют все слова указанные в запросе в качестве критерия отбора.
← →
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")
← →
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]
Не-а :)
ВСЕ слова из запроса так не пойдут.
← →
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:52) [3]я конечно щас не трезв :)) но почему не пойдут ?
← →
Polevi © (2004-04-10 21:53) [4]ааа, дошло :)
плохо вопрос прочитал сначала
← →
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 таблиц. Имхо, это не есть хорошо...
Поисковик пишешь? :)
← →
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. Эту работу я уже проделал, осталось поиск организовать, но на поиске застрял. Похоже не получится с помощью одного запроса, буду по другому делать.
Всем спасибо!
← →
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) - первичный ключ, т.е. нет повторений, работать должно.
← →
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 - таблица связи
← →
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, что и для разных значений.
А вообще решение прекрасное! Мой респект.
← →
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));
Появляется новый вопрос, как два запроса объединить в один, то есть первый запихнуть во второй?
← →
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, я думаю...
← →
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
← →
TGrey © (2004-04-13 21:34) [12]Пишет ошибка синтаксиса после в операторе FROM
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.03 c