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

Вниз

Оптимизация запроса   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.048 c
1-1190978060
wild_arg
2007-09-28 15:14
2007.12.16
группировка строк в TExcelApplication


2-1195626418
Неместная
2007-11-21 09:26
2007.12.16
фукнкция обратная Chr


4-1180599186
bns
2007-05-31 12:13
2007.12.16
Long file path


4-1179914782
Ангела
2007-05-23 14:06
2007.12.16
Как отследить, какие функции вызывает программа из Dll ?


15-1195061016
kernel
2007-11-14 20:23
2007.12.16
создал программу, "продвинул"... что дальше?