Задавайте вопросы, мы ответим
Вы не зашли.
Здравствуйте.
В базе имеется колонка, в которой в случайном порядке через пробел записаны слова. Необходимо составить запрос относительно нескольких слов, который вернет те записи, в которых есть одно или несколько из этих слов в любой комбинации и при этом нет ничего больше.
Например, на запрос со словами "aaa", "bbb", "ccc" могут вернуться (если они конечно есть в базе) записи с полем вида "aaa ccc bbb" или "bbb" или "bbb aaa", но не может вернуться "aaa ggg" или "bbb ccc yyy".
Ага, звучит как домашка по SQL, но вопрос реальный) подскажите пожалуйста.
Неактивен
Если набор слов ограниченный и никогда не меняется, то можно заменить
слова с пробелами на SET и, соответственно, сравнивать наборы через
равенство. Если же список слов произвольный, то ничего лучше
IN ('a b c', 'a c b', ..., 'a c', 'a b', ...) не придумаете.
Ну или, как вариант, написать свою udf, которая будет сортировать по сло-
вам, тогда список будет гораздо меньше. Впрочем, если писать udf, то лучше
сразу такую, которая будет говорить, совпадает или нет.
Неактивен
тут сразу возникает вопрос особенностей таблицы для облегчения запроса, типа длина слов одинакова ли? сколько слов? какие слова? итдитп
приведите несколько реальных строчек.
ЗЫ могу написать запрос на Oracle
Отредактированно Altukhov (25.01.2011 16:29:31)
Неактивен
Длина слов разная, русские символы, нижний регистр. Количество слов разное но в общем не менее 3-х. Кулинарная тематика, в колонке записаны ингредиенты подобно "курица картофель лук", "картофель макароны свинина сметана". Можно привести колонку к какому-либо стандарту (например упорядочить ингредиенты), если это поможет упростить запрос.
Идея с приведением слов к числам понравилась, спасибо. Запишу как спасительный вариант
Неактивен
можно написать вот такую функцию
create or replace function OCCURS
(cSearchExpression nvarchar2, cExpressionSearched nvarchar2)
return smallint
deterministic
as
begin
return nvl((length(cExpressionSearched) - nvl(length(replace(cExpressionSearched, cSearchExpression, '')),0)) / length(cSearchExpression),0);
end OCCURS;
она ищет подстроку в строке и выводит количтво раз, котрое встречается. пологаю, что не может быть написано "курица курица".
а ограничение нужно седлать по длине, т.е. длина строки ровна сумме длин тех слов, что встречаются в ней ( тут if). но это как-то сложно. и долго. и муторно.
а вообще у вас составлена таблица неправильно, нельзя столько элементов пихать в одну ячейку, распарсите и жизнь станет проще. а привести к виду который у вас можно очень просто при помощи конката.
Отредактированно Altukhov (26.01.2011 15:51:19)
Неактивен
Частично согласен с Altukhov — в рецепте всё равно нужно указывать
ингридиенты отдельно, так и сделайте табличку ингридиентов, и табличку
вхождений ингридиентов в рецепт. Это обычная нормализация данных,
но она упростит Вам жизнь
Неактивен
Спасибо за советы. Действительно стоило вынести их в отдельную таблицу. Буду переделывать, пока не поздно)
Неактивен