Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Помогите переписать запрос в конструкцию.  [new]
graph91
Member

Откуда:
Сообщений: 9
Добрый день, уважаемые форумчане!
Прошу не судить строго, если задаю глупые вопросы, но я начинающий, поэтому у меня их много и я много чего не умею.
Надеюсь на Вашу помощь.

Есть запрос:
SELECT a.C_1, b.C_10
FROM a, b
WHERE a.C_1 like '406%'
and (a.C_2=b.C_2)
AND (b.C_1 >= TO_DATE('30.06.2016', 'DD/MM/YYYY') and b.C_1 < TO_DATE('30/06/2016', 'DD/MM/YYYY') + 1)
and b.id=(select max(b.id)
FROM a, b
WHERE a.C_1 like '406%'
and (a.C_2=b.C_2)
AND (b.C_1 >= TO_DATE('30.06.2016', 'DD/MM/YYYY') and b.C_1 < TO_DATE('30/06/2016', 'DD/MM/YYYY') + 1))
Грубо говоря первым селектом я получаю много строк, а подзапросом я выбираю максимальный номер строки чтобы выбирать по каждому параметру не все строки, а только те, у которых номер максимальный.

Естественно условий больше и много строк. Поэтому запрос уходит надолго и зависает.

Подсказали, что можно воспользоваться курсором, а именно переписать в такую конструкцию:
DECLARE
Var1 NUMBER;
Var2 VARCHAR2(1000);
BEGIN
FOR e IN (select * from table…) LOOP
Var1:=e.field1;
Var2:=e.field2;
END LOOP;
END;

Прошу Вашей помощи, поскольку не совсем понимаю, что и куда пихать.

Заранее большое спасибо!
18 окт 16, 10:57    [19793533]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
stax..
Guest
graph91,

b.id уникально?

.....
stax
18 окт 16, 12:56    [19794289]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
graph91
Member

Откуда:
Сообщений: 9
stax..,
Да.
18 окт 16, 17:53    [19796027]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
stax..
Guest
graph91,

не могу врубится в логику запроса
подзапрос с мах вернет одно число мах(ид) (тоесть с b берем одну строку)

так тоже долго?

select * from (
SELECT a.C_1, b.C_10
,RANK() OVER (ORDER BY b.id DESC) r
FROM a, b
WHERE a.C_1 like '406%'
and (a.C_2=b.C_2)
AND (b.C_1 >= TO_DATE('30.06.2016', 'DD/MM/YYYY') and b.C_1 < TO_DATE('30/06/2016', 'DD/MM/YYYY') + 1)
)
WHERE r=1;

ps
мож переписать сам запрос
уйти от b.id=(select max(b.id)


ps
на счет FOR e IN (select * from table…)
а так понимаю предлагают
добавить order by, проветчить с мах и exit c цикла
stax
19 окт 16, 15:47    [19800496]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
Avotge
Guest
1. может как-то так?
SELECT MAX(a.c_1) KEEP(DENSE_RANK LAST ORDER BY b.id) a_c_1,
       MAX(b.c_10) KEEP(DENSE_RANK LAST ORDER BY b.id) b_c_10
  FROM a, b
 WHERE a.C_1 LIKE '406%'
   AND a.C_2=b.C_2
   AND b.C_1 BETWEEN TO_DATE('30.06.2016', 'DD/MM/YYYY') AND TO_DATE('30/06/2016', 'DD/MM/YYYY') + 1

2. Но скорее всего, надо смотреть план
3. Возможно, какая-то большая обработка и про курсор упомянули, чтобы обработку вести по частям?
Тогда например посмотреть условие по rownum, разбивку на диапазоны по rowid и тп
19 окт 16, 17:14    [19801010]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
Avotge
Guest
Ну и индексы по a.C_1 и по b.C_1 должны бы быть наверно )
При чем желательно имхо
индекс a(c_1, c_2)
и
индекс b(c_2, c_1)
Если запрос строится от таблицы "a".
Если от таблицы "b", то возможно
индекс a(c_2, c_1)
и
индекс b(c_1, c_2)
Как вариант, попробовать use_nl для этих a и b ) (поэтому тоже могли упомянуть цикл)
19 окт 16, 17:21    [19801057]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
stax..
Guest
Avotge,

запрос может возвращать несколько строк із а

.....
stax
19 окт 16, 17:32    [19801133]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
Avotge
Guest
stax.., точно, сори.
19 окт 16, 17:39    [19801181]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
Avotge
Guest
graph91
на счет FOR e IN (select * from table…)
а так понимаю предлагают
добавить order by, проветчить с мах и exit c цикла

Возможно, хотят, чтобы сразу достал максимальные Id cгруппировав по чему-либо (чему это вам виднее),
а потом уже в цикле брать эти id и подставлять во внешний запрос.
Надо или уточнять или решать с этим запросом, план, индексы и тд )

А может так? )
SELECT c_1, c_10 FROM 
      (SELECT /*+ use_nl(a b)*/
              a.c_1, b.c_10, 
              DENSE_RANK() over (order by b.id) AS rnk, 
              COUNT(DISTINCT ID) OVER() cnt
         FROM a, b
        WHERE a.C_1 LIKE '406%'
          AND a.C_2=b.C_2
          AND b.C_1 BETWEEN TO_DATE('30.06.2016', 'DD/MM/YYYY') and b.C_1 < TO_DATE('30/06/2016', 'DD/MM/YYYY'))
     WHERE rnk = cnt
19 окт 16, 17:56    [19801297]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
-2-
Member

Откуда:
Сообщений: 15330
graph91
задаю глупые вопросы
не майся дурью, от незнания sql незнание plsql не спасает.
19 окт 16, 18:01    [19801343]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
stax..
Guest
Avotge,

... order by b.id DESC =1

.....
stax
19 окт 16, 18:06    [19801373]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
Avotge
Guest
stax..., точно, проще, спасибо )
19 окт 16, 18:35    [19801471]     Ответить | Цитировать Сообщить модератору
 Re: Помогите переписать запрос в конструкцию.  [new]
graph91
Member

Откуда:
Сообщений: 9
Уважаемые форумчане, всем большое спасибо! Отдельное -
stax.. и Avotge за неравнодушие и помощь в решении проблемы!
Все получилось!
19 окт 16, 19:23    [19801598]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить