|
|
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
Допустим имеем такую таблицу: 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 в случае необходимости ) Вобщем кто чего сможет, подскажите... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2003, 16:13 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
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 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2003, 16:28 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
Тут может быть закавыка в том, что 2 агрегата совсем необязательно вернут данные одной строки, т.е. max(col1) может быть в одной строке, а max(col2) в другой. Можно так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 1-я строка в result-set'е и есть требуемый результат. Причем, коль уж уникальность данных оговорена не была, записей, одновременно удовлетворяющих условую, может быть несколько. Они будут идти друг за другом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2003, 16:36 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
2 Denis Popov Примерно так сейчас и сделано... но это не очень хороший вариант, т.к. представь себе таблицу в 100000 строк и все они попадают в условие... наблюдаем грустную картину, и даже если сделать select * from (....) where rownum < 2 все равно запрос работает долго. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2003, 16:48 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2003, 16:55 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
Что сказать... Надеюсь, составной индекс по (col1, col2, col3) существует? А если твой запрос теоретически способен возвратить 100,000 записей- может, в консерватории что-нибудь подправить надо? Попробуй открыть курсор с хинтом FIRST_ROW, профетчить первую запись и вернуть ее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2003, 16:59 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
нет, индекса я не строил. Zapros byl na Solaris F-15 First_Rows zdes ne pomoget, t.k. tebe nado yskorit' group by. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.02.2003, 17:18 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
2 Denis Popov Ну так вот я и хочу переписать запрос так, чтобы он возвращал только одну нужную мне строку. Составной индекс конечно есть. Но курсор мне кажется будет работать все-таки дольше чем select * from (....) where rownum < 2 хотя даже этот результат по быстродействию не устраивает. 2 Oracle X-pert А что за хитрый такой хинт /*+ PUSH_SUB(v)*/ ? 12,5 сек это много, максимум это 5. При том что в реальной таблице это условие может затрагивать до 5-ти столбцов в которых есть не только number но и varchar2. Да и все забыли про for update, а он нужен.... Сдается мне надо действительно переписать запрос как-то похитрее, я почти уверен, что это можно сделать, но вот как... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.02.2003, 10:22 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
2 Denis Popov а что в Вашем запросе дает условие where 1=1 ?? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.02.2003, 12:36 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
Это я так, выпендриваюсь:) Сказывается привычка собственного структурирования запросов, немного облегчающая (мне облегчающая) их отладку. Вот что-то мне подсказывает: если запрос может вернуть большую чать записей из таблицы, то вроде как FULL SCAN может быть самым дешевым вариантом. Другой вариант- сканирование только индекса, это тож можно попробовать сделать. Если еще такая штука под названием Fast Full-Index Scan, может она пригодится: http://www.oracle.com/oramag/oracle/98-Jul/index.html?dba.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.02.2003, 12:44 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
А вот такой вариант как? 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 до максимальной длины ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.02.2003, 14:09 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
не слева конечно а справа ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.02.2003, 14:10 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
Народ!!! Всем большое спасибо за участие... но тема не закрыта. Уточняю вопрос так как видимо не совсем корректно его изложил. для самого большого 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 не оставят эту проблемку без внимания ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.02.2003, 11:01 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
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) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.02.2003, 11:46 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
2 va_kochnev не пашет :((( для таблицы 1 1 1 2 2 2 5 5 5 вернуться должна 2 2 2 а у тебя no rows selected... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.02.2003, 11:55 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
Я ориентировался на твое первое письмо. Прогнал все insert-ы которые в нем перечислены и запрос вернул то, что ты и просил >Запрос должен выбрать только одну строку удовлетворяющую такому >условию (например) COL1 < 3, >для самого большого COL1 < 3 нужно найти самое большое COL2 < 5, для >самых больших COL1 < 3 и COL2 < 5 >нужно найти COL3 < 2 тоже самое большое. >Т.е. при таких условиях запрос должен вернуть строку >COL1 COL2 COL3 >---------- ---------- ---------- >2 2 1 Если что не так, то дай другой скрипт для теста ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.02.2003, 12:02 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
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 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.02.2003, 12:17 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
А как же все таки насчет >нужно найти COL3 < 2 тоже самое большое. или col3<=2 тоже устроит ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.02.2003, 12:20 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
"для самого большого 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? Потомучто тебе так хочется? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.02.2003, 12:45 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
Да нет col3<=2 не устроит... фишка в том, что "главным" условием должно быть условие по первому столбцу, следующее за ним по "главности" условие по втрому и т.д. т.е. если в таблице есть col1<3 и наибольшее из них col1=2 то все остальные условия должны проверяться только для col1=2 и если они не выполняются, то должна вернуться строка, которая удовлетворяет только превому условию. Вооот... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.02.2003, 12:52 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
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) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.02.2003, 13:45 |
|
||
|
подскажите как написать SQL запрос...
|
|||
|---|---|---|---|
|
#18+
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 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.02.2003, 14:22 |
|
||
|
|

start [/forum/topic.php?fid=52&msg=32112046&tid=1991682]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
185ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
53ms |
get tp. blocked users: |
1ms |
| others: | 236ms |
| total: | 512ms |

| 0 / 0 |
