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

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

Оптимизация запроса


alsov ©   (2007-08-09 12:39:00) 

Приветствую, Мастера

Помогите оптимизировать запрос.

Есть таблица

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)
---
--- если надо еще условий добавляем аналогично
)


Заранее спасибо за любу помощь


Кщд   (2007-08-13 14:24:00) [1]

>alsov ©   (13.08.07 13:20) [11]
если версия поддерживает аналитику, то можно и за один проход


alsov   (2007-08-13 13:20:00) [2]


> А как же Кроме того нужно чтобы все существующие 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


Johnmen   (2007-08-10 13:29:00) [3]


> alsov ©   (10.08.07 12:01) [9]
> остановился на вот таком варианте

А как же Кроме того нужно чтобы все существующие param выводились для obj_id, попадающего под условие.?
И зачем сэкономлено на else?


alsov   (2007-08-10 12:01:00) [4]

остановился на вот таком варианте

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 ....


viman   (2007-08-10 09:26:00) [5]

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-09 16:21:00) [6]


> Sergey13 ©   (09.08.07 15:34) [6]

Спасибо - попробую что быстрее.

Может еще какие-нибудь варианты будут?


Sergey13   (2007-08-09 15:34:00) [7]

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


Johnmen   (2007-08-09 15:29:00) [8]

Делай внутреннее соединение таблицы самой с собой столько раз, сколько означенных в [0] "условий", добавляя для каждого равенство на obj_id.


stanislav   (2007-08-09 15:23:00) [9]

stanislav ©   (09.08.07 13:31) [1]
Если нужно чтобы попадало
условие 1 и условие 2
значит нужно писать условие 1 OR условие 2, но не AND.
А вот что значит в вашем случае ИЛИ ? т.е. если попало условие 1, то условие 2 недолжно попасть?


alsov   (2007-08-09 15:11:00) [10]


> 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, попадающего под условие.


Sergey13   (2007-08-09 13:34:00) [11]

> [1] stanislav ©   (09.08.07 13:31)
Опередил! 8-)


stanislav   (2007-08-09 13:31:00) [12]

Не совсем понял, а чем так не устраивает ?

SELECT *
from tab1
WHERE (param_id=1 AND VAL LIKE 'Пот%') OR (param_id=2 AND VAL IS NOT NULL) OR ....

Какая СУБД?


Наверх

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