Форум: "Базы";
Текущий архив: 2007.12.16;
Скачать: [xml.tar.bz2];
ВнизОптимизация запроса Найти похожие ветки
← →
alsov © (2007-08-09 12:39) [0]Приветствую, Мастера
Помогите оптимизировать запрос.
Есть таблица
CREATE TABLE TAB1 (
obj_id NUMBER(10,0) NOT NULL,
param_id NUMBER(10,0) NOT NULL,
val VARCHAR2(2000) NULL
)
Надо сделать выборку объектов со всеми параметрами, у которых имеется связка (param_id=10 and val LIKE "Текст%").
Причем связок таких может быть как угодно много и соединять их можно как по И так и по ИЛИ.
У меня получилось примерно следующее, но мне кажентся этот способ не оптимален.
SELECT *
FROM tab1
WHERE obj_id IN (
-- первое условие
select obj_id
from tab1
WHERE (param_id=1 AND VAL LIKE "Пот%")
---
INTERSECT -- если условие или поменять на UNION
-- второе услвие
select obj_id
from tab1
WHERE (param_id=2 AND VAL IS NOT NULL)
---
--- если надо еще условий добавляем аналогично
)
Заранее спасибо за любу помощь
← →
stanislav © (2007-08-09 13:31) [1]Не совсем понял, а чем так не устраивает ?
SELECT *
from tab1
WHERE (param_id=1 AND VAL LIKE "Пот%") OR (param_id=2 AND VAL IS NOT NULL) OR ....
Какая СУБД?
← →
Sergey13 © (2007-08-09 13:34) [2]> [1] stanislav © (09.08.07 13:31)
Опередил! 8-)
← →
alsov © (2007-08-09 15:11) [3]
> stanislav © (09.08.07 13:31) [1]
> Какая СУБД?
>
ORACLE
>
> Не совсем понял, а чем так не устраивает ?
>
> SELECT *
> from tab1
> WHERE (param_id=1 AND VAL LIKE "Пот%") OR (param_id=2 AND
> VAL IS NOT NULL) OR ....
подходит, но только для варианта ИЛИ, а для варианта И нет, т.к. нужно вывести obj_id у которых и (param_id=1 AND VAL LIKE "Пот%"), и (param_id=2 AND VAL IS NOT NULL) и ...
а если написать (param_id=1 AND VAL LIKE "Пот%") AND (param_id=2 AND
> VAL IS NOT NULL) то естественно ничего не выведет.
Кроме того нужно чтобы все существующие param выводились для obj_id, попадающего под условие.
← →
stanislav © (2007-08-09 15:23) [4]stanislav © (09.08.07 13:31) [1]
Если нужно чтобы попадало
условие 1 и условие 2
значит нужно писать условие 1 OR условие 2, но не AND.
А вот что значит в вашем случае ИЛИ ? т.е. если попало условие 1, то условие 2 недолжно попасть?
← →
Johnmen © (2007-08-09 15:29) [5]Делай внутреннее соединение таблицы самой с собой столько раз, сколько означенных в [0] "условий", добавляя для каждого равенство на obj_id.
← →
Sergey13 © (2007-08-09 15:34) [6]> [3] alsov © (09.08.07 15:11)
Тогда у тебя нормальный запрос. Можно еще вместо IN попробовать EXIST и покрутить с ним - иногда производительность выше. Типа
SELECT *
FROM tab1
WHERE exists(
-- первое условие
select 1
from tab1
WHERE (param_id=1 AND VAL LIKE "Пот%")
)
---
AND -- если условие или поменять на OR
-- второе услвие
(select 1
from tab1
WHERE (param_id=2 AND VAL IS NOT NULL)
)
← →
alsov © (2007-08-09 16:21) [7]
> Sergey13 © (09.08.07 15:34) [6]
Спасибо - попробую что быстрее.
Может еще какие-нибудь варианты будут?
← →
viman © (2007-08-10 09:26) [8]select obj_id
from tab1
WHERE (:p_case1 <> 0 and (param_id=1 AND VAL LIKE "Пот%"))
or (:p_case2 <> 0 and (param_id=2 AND VAL IS NOT NULL))
or (:p_case3 <> 0 and (...))
....
Сделай так и включай нужное условие установкой нужного параметра <> 0, если же условие не нужно, то = 0.
← →
alsov © (2007-08-10 12:01) [9]остановился на вот таком варианте
select obj_id
from tab1
group by obj_id
having count(case when (param_id=1 AND VAL LIKE "Пот%") then 1 end) > 0
and count(case when (param_id=2 AND VAL IS NOT NULL) then 1 end ) > 0
and ....
← →
Johnmen © (2007-08-10 13:29) [10]
> alsov © (10.08.07 12:01) [9]
> остановился на вот таком варианте
А как жеКроме того нужно чтобы все существующие param выводились для obj_id, попадающего под условие.
?
И зачем сэкономлено на else?
← →
alsov © (2007-08-13 13:20) [11]
> А как же Кроме того нужно чтобы все существующие param выводились
> для obj_id, попадающего под условие.?
Чуть не дописал
select * from tab1
where obj_id in (
select obj_id
from tab1
group by obj_id
having count(case when (param_id=1 AND VAL LIKE "Пот%") then 1 end) > 0
and count(case when (param_id=2 AND VAL IS NOT NULL) then 1 end ) > 0
and ....
)
> И зачем сэкономлено на else?
А зачем писать, если он не нужен
ведь при сравнении с null всегда false
← →
Кщд © (2007-08-13 14:24) [12]>alsov © (13.08.07 13:20) [11]
если версия поддерживает аналитику, то можно и за один проход
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2007.12.16;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.048 c