Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Oracle having first / 25 сообщений из 27, страница 1 из 2
28.11.2016, 22:34
    #39356406
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
Коллеги, помогите дилетанту
правильно записать подобную конструкцию:

GROUP BY obv.numopzn, obv.dateizm
HAVING FIRST ORDER BY obv.numopzn, obv.dateizm DESC;

С уважением,
Владимир.
...
Рейтинг: 0 / 0
28.11.2016, 23:44
    #39356426
что это
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
ВМоисеев, и что же должен делать HAVING FIRST?
...
Рейтинг: 0 / 0
29.11.2016, 00:11
    #39356440
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
ВМоисеевКоллеги, помогите дилетанту
правильно записать подобную конструкцию:

GROUP BY obv.numopzn, obv.dateizm
HAVING FIRST ORDER BY obv.numopzn, obv.dateizm DESC;

Если я правильно понял, то на 12с это будет
Код: plsql
1.
2.
3.
 GROUP BY obv.numopzn, obv.dateizm
 ORDER BY obv.numopzn, obv.dateizm DESC
 fetch FIRST '1' rows only;


На версиях постарше
Код: plsql
1.
2.
3.
4.
5.
select * from (
...
 GROUP BY obv.numopzn, obv.dateizm
 ORDER BY obv.numopzn, obv.dateizm DESC
) where rownum <2;


или
Код: plsql
1.
2.
3.
4.
5.
6.
select * from (
select ...
, row_number() over(ORDER BY obv.numopzn, obv.dateizm DESC) rn
...
 GROUP BY obv.numopzn, obv.dateizm
) where rn=1;
...
Рейтинг: 0 / 0
29.11.2016, 02:09
    #39356476
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
>что это, вчера, 23:44 [19945086]
> ... что же должен делать ...

Есть некоторое множество объектов. Каждый объект характеризуется своим состоянием.
В некоторые случайные моменты времени состояние объекта меняется
и фиксируется до следующего изменения.
Клиент хочет знать состояние объектов на определенное время (дату).

С уважением,
Владимир.
...
Рейтинг: 0 / 0
29.11.2016, 02:44
    #39356482
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
ВМоисеевКлиент хочет знать состояние объектов на определенное время (дату).


Код: plsql
1.
2.
3.
4.
5.
6.
select  object_id,
        max(state) keep(last dense_rank order by state_date) state
  from  objects
  where state_date <= определенное_время
  GROUP BY object_id
/



SY.
...
Рейтинг: 0 / 0
29.11.2016, 03:18
    #39356485
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
Или через аналитику:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with t as (
           select  o.*,
                   row_number() over(partition by object_id order by state_date desc) rn
             from  objects
             state_date <= определенное_время
          )
select  *
  from  t
  where rn = 1
/



SY.
...
Рейтинг: 0 / 0
29.11.2016, 03:21
    #39356486
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
>SY, сегодня, 02:44 [19945338]
>select object_id ...

Да, каждый объект имеет:
object_id,
object_name,
object_p1,
...
object_pn,
object_date.

Я работаю с PLSQL Developer, и здесь Ваша конструкция GROUP BY object_id,
только с одним object_id даёт ошибку.
И не понятно, для чего max(state)? Зачем?

С уважением,
Владимир
...
Рейтинг: 0 / 0
29.11.2016, 03:36
    #39356489
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
>SY,сегодня, 03:18 [19945346]
>Или через аналитику:

Огромное спасибо и многие лета Вам.
То что надо.

С уважением,
Владимир
...
Рейтинг: 0 / 0
29.11.2016, 04:10
    #39356492
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
>SY, сегодня, 03:18 [19945346]
>Или через аналитику:

Рано радовался.
Не могу встроить эту конструкцию в процедуру пакета.
Не подскажете ?
В SQL окне выполняется штатно.

С уважением,
Владимир.
...
Рейтинг: 0 / 0
29.11.2016, 04:27
    #39356495
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
ВМоисеевНе могу встроить эту конструкцию в процедуру пакета.


Bерсия?
Ну и код в студию.

SY.
...
Рейтинг: 0 / 0
29.11.2016, 04:36
    #39356496
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
ВМоисеевИ не понятно, для чего max(state)? Зачем?


Код: plsql
1.
max(state) keep(last dense_rank order by state_date) state



Сортируем по state_date (order by). Присваиваем ранг (dense_rank). Берем наибольший ранг (last). Но ведь строк с наибольшим рангом может быть несколько и с разными state. Вот для этого и нужна агрегирующая функция - в данном случае я выбрал max.

SY.
...
Рейтинг: 0 / 0
29.11.2016, 04:50
    #39356498
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
>SY, сегодня, 04:27 [19945362]
>Bерсия?

Oracle 8.
Как отдельный SELECT проходит, ошибка при встраивании в процедуру пакета на строке row_number() после over.

SELECT *
FROM(
SELECT
row_number() over(partition by obv.numopzn order by obv.dateizm desc) rn
, obv.numopzn numopzn

. . .

)
WHERE rn=1;

С уважением,
Владимир.
...
Рейтинг: 0 / 0
29.11.2016, 07:57
    #39356517
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
ВМоисеевOracle 8.Соболезнуем.
...
Рейтинг: 0 / 0
29.11.2016, 08:04
    #39356521
Вячеслав Любомудров
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
Ну, row_number - то уже работал, просто любая аналитика в EXECUTE IMMEDIATE
...
Рейтинг: 0 / 0
29.11.2016, 10:48
    #39356612
Vint
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
Вячеслав Любомудров,
Если мне не изменяет память, то аналитика появилась во втором релизе восьмерки. так что не факт что динамика спасёт автора....))
...
Рейтинг: 0 / 0
29.11.2016, 10:53
    #39356618
Вячеслав Любомудров
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
Спасет-спасет, раз у него за пределами PL/SQL выполняется
Старые грабли
...
Рейтинг: 0 / 0
29.11.2016, 11:33
    #39356666
Vint
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
Вячеслав Любомудров,
Да, пропустил про "штатно". Зато вспомнил как обходились без аналитики через pl/sql)
...
Рейтинг: 0 / 0
01.12.2016, 02:37
    #39358120
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
>Вячеслав Любомудров, 29 ноя 16, 10:53 [19946097]
>Спасет-спасет...

Точно - спасло.
Огромное спасибо.

С уважением,
Владимир.
...
Рейтинг: 0 / 0
10.12.2016, 01:04
    #39363933
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
>Вячеслав Любомудров, 29 ноя 16, 10:53 [19946097]
>Спасет-спасет...

Увы, на объекте промышленности не спасло. Не работают аналитические функции.
Но задача показа состояния объектов базы данных должна быть решена.
Вопрос, как очистить временную таблицу?

С уважением,
Владимир.
...
Рейтинг: 0 / 0
10.12.2016, 03:01
    #39363951
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
ВМоисеевВопрос, как очистить временную таблицу?


Какую временную таблицу?

Ты думаешь этот тип задач до аналитики не существовал? Очень даже существовал. И ничего, крутились и бeз аналитики:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
CREATE OR REPLACE
  FUNCTION LAST_STATE(
                      P_OBJECT_ID      NUMBER,
                      P_MAX_STATE_DATE DATE
                     )
    RETURN VARCHAR2
    IS
        V_STATE VARCHAR2(20);
    BEGIN
        SELECT  MAX(STATE)
          INTO  V_STATE
          FROM  OBJECTS
          WHERE OBJECT_ID  = P_OBJECT_ID
            AND STATE_DATE = P_MAX_STATE_DATE;
        RETURN V_STATE;
END;
/
SELECT  OBJECT_ID,
        LAST_STATE(OBJECT_ID,MAX(STATE_DATE)) STATE
  FROM  OBJECTS
  WHERE STATE_DATE <= определенное_время
  GROUP BY OBJECT_ID
/



А эффективней всего "бабушкиным методом":

Код: plsql
1.
2.
3.
4.
5.
6.
SELECT  OBJECT_ID,
        SUBSTR(MAX(TO_CHAR(STATE_DATE,'YYYYMMDDHH24MISS') || STATE),15) STATE
  FROM  OBJECTS
  WHERE STATE_DATE <= определенное_время
  GROUP BY OBJECT_ID
/



SY.
...
Рейтинг: 0 / 0
10.12.2016, 13:34
    #39364045
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
>SY, сегодня, 03:01 [19987267]

>Ты думаешь этот тип задач до аналитики не существовал?
Извините, я об этом даже не думал. Есть задача, её надо решить.

>А эффективней всего "бабушкиным методом": ...
Это не решение задачи.
Состояние объекта определяется несколькими параметрами.
И вариант MAX() или с другими аналогичными функциями по отдельным параметрам состояния не катит.
Нужна FIRST(), но её нет.

Вот моё решение:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
 procedure get_PrebivanieTB(
   cur_viborka out t_cursor
   ,xdate in date
 )
 is
 BEGIN
  DELETE FROM  tbl_tmp_gis;
  COMMIT;
  INSERT INTO tbl_tmp_gis 
   SELECT 
     ... 
   FROM
     ...
   WHERE
     ...
    AND TRUNC(obv.dateizm) <= TRUNC(xdate);

  open cur_viborka for 
  SELECT tbl_tmp_gis.*
  FROM 
    tbl_tmp_gis
   ,( 
     SELECT 
       tbl_tmp_gis.numopzn numopzn
      ,MAX(tbl_tmp_gis.dateizm) dateizm
     FROM tbl_tmp_gis
     GROUP BY tbl_tmp_gis.numopzn
   ) t2
  WHERE
    tbl_tmp_gis.numopzn=t2.numopzn
   AND tbl_tmp_gis.dateizm=t2.dateizm;

  DELETE FROM  tbl_tmp_gis;
  COMMIT;
 
END   get_PrebivanieTB; 

где tbl_tmp_gis есть:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 CREATE GLOBAL TEMPORARY TABLE tbl_tmp_gis(
     numopzn VARCHAR2(30)
    ,namvrr VARCHAR2(55)
    ,numdoc VARCHAR2(20)
    ,mesto VARCHAR2(255)
    ,lat VARCHAR2(7)
    ,lng VARCHAR2(8)
    ,dateizm DATE 
  )
  ON COMMIT PRESERVE ROWS



Эта конструкция работает на тесте в два раза быстрее, чем с аналитической функцией row_number().

С уважением,
Владимир
...
Рейтинг: 0 / 0
10.12.2016, 14:13
    #39364066
stax..
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
ВМоисеев>SY, сегодня, 03:01 [19987267]

>Ты думаешь этот тип задач до аналитики не существовал?
Извините, я об этом даже не думал. Есть задача, её надо решить.

>А эффективней всего "бабушкиным методом": ...
Это не решение задачи.
Состояние объекта определяется несколькими параметрами.
И вариант MAX() или с другими аналогичными функциями по отдельным параметрам состояния не катит.
Нужна FIRST(), но её нет.

Вот моё решение:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
 procedure get_PrebivanieTB(
   cur_viborka out t_cursor
   ,xdate in date
 )
 is
 BEGIN
  DELETE FROM  tbl_tmp_gis;
  COMMIT;
  INSERT INTO tbl_tmp_gis 
   SELECT 
     ... 
   FROM
     ...
   WHERE
     ...
    AND TRUNC(obv.dateizm) <= TRUNC(xdate);

  open cur_viborka for 
  SELECT tbl_tmp_gis.*
  FROM 
    tbl_tmp_gis
   ,( 
     SELECT 
       tbl_tmp_gis.numopzn numopzn
      ,MAX(tbl_tmp_gis.dateizm) dateizm
     FROM tbl_tmp_gis
     GROUP BY tbl_tmp_gis.numopzn
   ) t2
  WHERE
    tbl_tmp_gis.numopzn=t2.numopzn
   AND tbl_tmp_gis.dateizm=t2.dateizm;

  DELETE FROM  tbl_tmp_gis;
  COMMIT;
 
END   get_PrebivanieTB; 

где tbl_tmp_gis есть:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 CREATE GLOBAL TEMPORARY TABLE tbl_tmp_gis(
     numopzn VARCHAR2(30)
    ,namvrr VARCHAR2(55)
    ,numdoc VARCHAR2(20)
    ,mesto VARCHAR2(255)
    ,lat VARCHAR2(7)
    ,lng VARCHAR2(8)
    ,dateizm DATE 
  )
  ON COMMIT PRESERVE ROWS



Эта конструкция работает на тесте в два раза быстрее, чем с аналитической функцией row_number().

С уважением,
Владимир

не понял
если все ето в pl/sql
то
GROUP BY obv.numopzn, obv.dateizm
/*HAVING FIRST*/ ORDER BY obv.numopzn, obv.dateizm DESC
фетчим первые и exit

.....
stax
...
Рейтинг: 0 / 0
10.12.2016, 15:36
    #39364082
ВМоисеев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
>stax.., сегодня, 14:13 [19987828]

> ... если все ето в pl/sql ...
Да. Это всё в pl/sql.
Если Вас не затруднит, разверните вашу схему решения в текст на pl/sql.

Когда меня приперли к стенке на объекте, я примерно так и поступил:
. . .
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
  open cur_viborka for 
  SELECT
   . . .
  FROM
   . . . 
  WHERE
   . . .
   AND TRUNC(obv.dateizm) <= xdate;
  ORDER BY ORDER BY obv.numopzn, obv.dateizm DESC;



отправив все строки огромной выборки на клиента.
Там нет проблем выбрать первую строку из каждой группы.
Схема работает, но сами понимаете ...

С уважением,
Владимир
...
Рейтинг: 0 / 0
10.12.2016, 16:09
    #39364091
stax..
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
ВМоисеев>что это, вчера, 23:44 [19945086]
> ... что же должен делать ...

Есть некоторое множество объектов. Каждый объект характеризуется своим состоянием.
В некоторые случайные моменты времени состояние объекта меняется
и фиксируется до следующего изменения.
Клиент хочет знать состояние объектов на определенное время (дату).

С уважением,
Владимир.
давайте вернемся к исходному
чем Вас не устраивает решение SY?

ето обычная задачка, я называю ее курс на дату

по разному можно
where (id,dat) in (select id,max(dat) from t where dat<='dd' ... group by id)
или с кореляцией
і тд
непонятно что не подходит

зи
желательно чтоб был индекс по id (в ідеале id,dat)

.....
stax
...
Рейтинг: 0 / 0
10.12.2016, 16:11
    #39364092
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Oracle having first
ВМоисеевНужна FIRST(), но её нет.


Давай определяться. Задача была опмсана так:

ВМоисеевЕсть некоторое множество объектов. Каждый объект характеризуется своим состоянием.
В некоторые случайные моменты времени состояние объекта меняется
и фиксируется до следующего изменения.
Клиент хочет знать состояние объектов на определенное время (дату).


Затем рабочee для > Oracle 8 решение:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT * 
FROM( 
SELECT 
row_number() over(partition by obv.numopzn order by obv.dateizm desc) rn
, obv.numopzn numopzn

. . .

) 
WHERE rn=1; 



которое нужно воплотить в Oracle 8.
Теперь:

ВМоисеев>А эффективней всего "бабушкиным методом": ...
Это не решение задачи.
Состояние объекта определяется несколькими параметрами.
И вариант MAX() или с другими аналогичными функциями по отдельным параметрам состояния не катит.
Нужна FIRST(), но её нет.


Втыкаем "бабушкин метод":

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT 
obv.numopzn numopzn

. . .

WHERE ROWID IN (
                SELECT SUBSTR(MAX(TO_CHAR(STATE_DATE,'YYYYMMDDHH24MISS') || ROWID),15) 
                  FROM  
                  WHERE STATE_DATE <= определенное_время
                  GROUP BY numopzn
               )



Например данные о последнем на 31 Декабря 1997 принятом сотруднике по отделам:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
SELECT  *
  FROM  HR.EMPLOYEES
  WHERE ROWID IN (
                  SELECT  SUBSTR(MAX(TO_CHAR(HIRE_DATE,'YYYYMMDD') || ROWID),9)
                    FROM  HR.EMPLOYEES
                    WHERE HIRE_DATE <= DATE '1997-12-31'
                    GROUP BY DEPARTMENT_ID
                 )
  ORDER BY DEPARTMENT_ID
/

EMPLOYEE_ID FIRST_NAME           LAST_NAME                 EMAIL                     PHONE_NUMBER         HIRE_DATE JOB_ID         SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
----------- -------------------- ------------------------- ------------------------- -------------------- --------- ---------- ---------- -------------- ---------- -------------
        200 Jennifer             Whalen                    JWHALEN                   515.123.4444         17-SEP-87 AD_ASST          4400                       101            10
        202 Pat                  Fay                       PFAY                      603.123.6666         17-AUG-97 MK_REP           6000                       201            20
        116 Shelli               Baida                     SBAIDA                    515.127.4563         24-DEC-97 PU_CLERK         2900                       114            30
        203 Susan                Mavris                    SMAVRIS                   515.123.7777         07-JUN-94 HR_REP           6500                       101            40
        130 Mozhe                Atkinson                  MATKINSO                  650.124.6234         30-OCT-97 ST_CLERK         2800                       121            50
        105 David                Austin                    DAUSTIN                   590.423.4569         25-JUN-97 IT_PROG          4800                       103            60
        204 Hermann              Baer                      HBAER                     515.123.8888         07-JUN-94 PR_REP          10000                       101            70
        160 Louise               Doran                     LDORAN                    011.44.1345.629268   15-DEC-97 SA_REP           7500             .3        146            80
        102 Lex                  De Haan                   LDEHAAN                   515.123.4569         13-JAN-93 AD_VP           17000                       100            90
        111 Ismael               Sciarra                   ISCIARRA                  515.124.4369         30-SEP-97 FI_ACCOUNT       7700                       108           100
        206 William              Gietz                     WGIETZ                    515.123.8181         07-JUN-94 AC_ACCOUNT       8300                       205           110

11 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Oracle having first / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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