powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / подскажите как написать SQL запрос...
23 сообщений из 23, страница 1 из 1
подскажите как написать SQL запрос...
    #32109979
Um
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Допустим имеем такую таблицу:

create table test (col1 number(3), col2 number(3), col3 number(3));

insert into test values (1,1,1);
insert into test values (1,1,2);
insert into test values (1,2,2);
insert into test values (1,2,1);
insert into test values (2,1,1);
insert into test values (2,1,2);
insert into test values (2,2,1);
insert into test values (2,2,2);
insert into test values (3,1,1);
insert into test values (3,1,2);
insert into test values (3,2,1);
insert into test values (3,2,2);

select * from test;

COL1 COL2 COL3
---------- ---------- ----------
1 1 1
1 1 2
1 2 2
1 2 1
2 1 1
2 1 2
2 2 1
2 2 2
3 1 1
3 1 2
3 2 1
3 2 2


Запрос должен выбрать только одну строку удовлетворяющую такому условию (например) COL1 < 3,
для самого большого COL1 < 3 нужно найти самое большое COL2 < 5, для самых больших COL1 < 3 и COL2 < 5
нужно найти COL3 < 2 тоже самое большое.
Т.е. при таких условиях запрос должен вернуть строку

COL1 COL2 COL3
---------- ---------- ----------
2 2 1

ессно хорошо бы, чтоб он имел приличный план выполнения Т.к. работать он будет на больших таблицах.
И надо еще чтоб этот запрос можно было использовать с for update в случае необходимости )
Вобщем кто чего сможет, подскажите...
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32109985
Фотография Oracle X-pert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Regards!

select /*+ PUSH_SUB(v)*/
max(col1),max(col2),col3 from
(
select max(col1) col1 ,max(col2) col2,max(col3) col3
from test t
where col1 < 3
and col3 < 2
and col2 < 5
group by col1,col3) v
group by col3
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32109995
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут может быть закавыка в том, что 2 агрегата совсем необязательно вернут данные одной строки, т.е. max(col1) может быть в одной строке, а max(col2) в другой. Можно так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
select t.col1
     , t.col2
     , t.col3
from (
  select t.*
  from test t
  where  1 = 1 
    and t.col1 <  3 
    and t.col2 <  5 
    and t.col3 <  2 
) t
order by t.col1 desc
       , t.col2 desc
       , t.col3 desc

1-я строка в result-set'е и есть требуемый результат. Причем, коль уж уникальность данных оговорена не была, записей, одновременно удовлетворяющих условую, может быть несколько. Они будут идти друг за другом.
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32110004
Um
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Denis Popov

Примерно так сейчас и сделано... но это не очень хороший вариант, т.к. представь себе таблицу в 100000 строк и все они попадают в условие... наблюдаем грустную картину, и даже если сделать select * from (....) where rownum < 2
все равно запрос работает долго.
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32110009
Фотография Oracle X-pert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Voobshe-to , vheshnii select rabotaet s RECORDSET, tak-chto vse ravno vytanet nugnoe.
Ny a naschet performance -
1 Ispolzovat' HINT
2. Esli ty rabotaesh s SQL99, to ispolzui opziu OVER (Partition by....).
Regards!

P.S. Test on UNIX/Oracle8i na 10000000 rows dal resultat cheres 12,5 sec.
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32110012
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что сказать... Надеюсь, составной индекс по (col1, col2, col3) существует? А если твой запрос теоретически способен возвратить 100,000 записей- может, в консерватории что-нибудь подправить надо? Попробуй открыть курсор с хинтом FIRST_ROW, профетчить первую запись и вернуть ее.
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32110020
Фотография Oracle X-pert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
нет, индекса я не строил.
Zapros byl na Solaris F-15
First_Rows zdes ne pomoget, t.k. tebe nado yskorit' group by.
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32110627
Um
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Denis Popov
Ну так вот я и хочу переписать запрос так, чтобы он возвращал только одну нужную мне строку. Составной индекс конечно есть. Но курсор мне кажется будет работать все-таки дольше чем select * from (....) where rownum < 2 хотя даже этот результат по быстродействию не устраивает.

2 Oracle X-pert
А что за хитрый такой хинт /*+ PUSH_SUB(v)*/ ?
12,5 сек это много, максимум это 5. При том что в реальной таблице это условие может затрагивать до 5-ти столбцов в которых есть не только number но и varchar2.

Да и все забыли про for update, а он нужен....
Сдается мне надо действительно переписать запрос как-то похитрее, я почти уверен, что это можно сделать, но вот как...
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32110755
Um
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Denis Popov
а что в Вашем запросе дает условие
where 1=1 ??
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32110760
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это я так, выпендриваюсь:) Сказывается привычка собственного структурирования запросов, немного облегчающая (мне облегчающая) их отладку.

Вот что-то мне подсказывает: если запрос может вернуть большую чать записей из таблицы, то вроде как FULL SCAN может быть самым дешевым вариантом. Другой вариант- сканирование только индекса, это тож можно попробовать сделать. Если еще такая штука под названием Fast Full-Index Scan, может она пригодится:
http://www.oracle.com/oramag/oracle/98-Jul/index.html?dba.html
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32110822
Alex_D
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот такой вариант как?

select * from test
where to_char(col1)||to_char(col2)||to_char(col3) =
(select max(to_char(col1)||to_char(col2)||to_char(col3))from test
where COL1 < 3
and COL2 < 5
and COL3 < 2)

Если в столбцах значения больше чем однозначные то дополнить строчки слева 0 до максимальной длины ...
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32110825
Alex_D
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не слева конечно а справа ...
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32111936
Um
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Народ!!!
Всем большое спасибо за участие... но тема не закрыта.
Уточняю вопрос так как видимо не совсем корректно его изложил.
для самого большого COL1 < 3 нужно найти самое большое COL2 < 5, для самых больших COL1 < 3 и COL2 < 5
нужно найти COL3 < 2 тоже самое большое.
т.е. если в таблице есть
1 1 1
2 2 2
5 5 5

то вернуться должна
2 2 2
несмотря на то, что условие COL3 < 2 жесткое.
Также напомню, что вернуться должна одна строка. И хотельсь бы иметь возможность применять этот же запрос с for update.
Я надеюсь, что мастера SQL не оставят эту проблемку без внимания
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32111972
va_kochnev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
select*from test a where
col1=(select max(col1) from test x where col1<3)
and col2=(select max(col2) from test b where b.col1=a.col1 and b.col2<5)
and col3=(select max(col3) from test c where a.col1=c.col1 and a.col2=c.col2 and c.col3<2)
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32111984
Um
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 va_kochnev
не пашет :(((
для таблицы
1 1 1
2 2 2
5 5 5

вернуться должна
2 2 2

а у тебя no rows selected...
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32111990
va_kochnev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я ориентировался на твое первое письмо. Прогнал все insert-ы которые в нем перечислены и запрос вернул то, что ты и просил

>Запрос должен выбрать только одну строку удовлетворяющую такому >условию (например) COL1 < 3,
>для самого большого COL1 < 3 нужно найти самое большое COL2 < 5, для >самых больших COL1 < 3 и COL2 < 5
>нужно найти COL3 < 2 тоже самое большое.
>Т.е. при таких условиях запрос должен вернуть строку

>COL1 COL2 COL3
>---------- ---------- ----------
>2 2 1

Если что не так, то дай другой скрипт для теста
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32112005
Um
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drop table test;
create table test (col1 number(3), col2 number(3), col3 number(3));

insert into test values (1,1,1);
insert into test values (2,2,2);
insert into test values (5,5,5);

запрос с условиями из первого поста должен вернуть
2 2 2
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32112010
va_kochnev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А как же все таки насчет
>нужно найти COL3 < 2 тоже самое большое.

или col3<=2 тоже устроит ?
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32112046
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"для самого большого COL1 < 3 нужно найти самое большое COL2 < 5, для самых больших COL1 < 3 и COL2 < 5
нужно найти COL3 < 2 тоже самое большое.
т.е. если в таблице есть
1 1 1
2 2 2
5 5 5

то вернуться должна
2 2 2
несмотря на то, что условие COL3 < 2 жесткое."

Это противоречивое условие. В любом случае нельзя выбрать строку 2 2 2, если жёстко стоит условие COL3 < 2.
Я понимаю, что тебе хочется получить именно эту строку интуитивно, но в данном случае твоя интуиция не соответствует критерию COL3<2.

1) COL1 < 3, получаем
1 1 1
2 2 2 - самое большлое COL1
2) На входе второго условия имеем только одну строку
2 2 2
COL2<5
2 2 2
3) COL3< 2
Всё, ничего не осталось.

Поэтому вопрос: с какой стати должна остаться строка 2 2 2?

Потомучто тебе так хочется?
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32112052
Um
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да нет col3<=2 не устроит...
фишка в том, что "главным" условием должно быть условие по первому столбцу, следующее за ним по "главности" условие по втрому и т.д.
т.е. если в таблице есть col1<3 и наибольшее из них col1=2 то все остальные условия должны проверяться только для col1=2 и если они не выполняются, то должна вернуться строка, которая удовлетворяет только превому условию.
Вооот...
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32112090
Фотография Oracle X-pert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
select /*+ PUSH_SUB(v)*/
col1,col2,col3 , co from
(
select max(col1) col1 ,max(col2) col2,max(col3) col3 ,GROUPING(col1) AS Co
from test t
where col1 < 3
and ( col1 < 3 or col3 < 2 )
and ( col1 < 3 or col2 < 5 )
group BY ROLLUP (col1,col3)) v
where co = 1

Result:
COL1 COL2 COL3 CO
2 2 2 1

Column col1 ( recommended ) indexed.


Runtime::~ 0.12 sec on (1.000.000.000 rows on F15)
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32112129
Фотография Oracle X-pert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
toge rabotaet:
select /*+ PUSH_SUB(v)*/
col1,col2,col3 , co from
(
select max(col1) col1 ,max(col2) col2,max(col3) col3 ,GROUPING(col1) AS Co
from test t
where col1 < 3
or( col1 < 3 and col3 < 2 )
or ( col1 < 3 and col2 < 5 )
group BY ROLLUP (col1,col3)) v
--where co = 1
...
Рейтинг: 0 / 0
подскажите как написать SQL запрос...
    #32112245
Um
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to Oracle X-pert:
В последнем варианте запрос может выдать несколько строк...
а за первый спасибо, буду проверять.
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / подскажите как написать SQL запрос...
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]