powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Оптимизировать запрос
22 сообщений из 22, страница 1 из 1
Оптимизировать запрос
    #39560751
cobalt_frog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть запрос:
Код: plsql
1.
2.
3.
4.
5.
select  t1.create_date
        ,t1.type
        ,t2.create_date old_create_date
        ,t2.type  old_create_date
  from  t1.id = t2.id



необходимо достать все записи у которых отличаются поля create_date(тип дата) или type, при этом эти поля могут иметь значени null(если новое значение null, то его возвращать не надо).
Я сделал след макаром:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select  t1.create_date
        ,t1.type
        ,t2.create_date old_create_date
        ,t2.type  old_type
  from  t1.id = t2.id
 where  type        is not null
   and  create_date is not null
   and  (nvl(old_type,'1') != type or nvl(old_create_date,to_date('01.01.1899','dd.mm.yyyy')) != create_date);


Можно ли его сделать эффективнее/красивее?
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39560756
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cobalt_frog,

Для начала убери

Код: plsql
1.
2.
type        is not null
   and  create_date is not null



SY.
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39560759
cobalt_frog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY,

Согласен) спс.
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39560797
cobalt_frog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY,

а вообще то нет, условия необходимо оставить...если type is null, а create_date not null и равна old_create_date, то запись отберется.
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39560800
cobalt_frog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cobalt_frog,

если type is null, а create_date not null и не равна old_create_date, то запись отберется.
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39560947
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это в каком oracle такой синтаксис разрешён:
Код: plsql
1.
from  t1.id = t2.id


?
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39560951
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cobalt_frogЯ сделал след макаром:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select  t1.create_date
        ,t1.type
        ,t2.create_date old_create_date
        ,t2.type  old_type
  from  t1.id = t2.id
 where  type        is not null
   and  create_date is not null
   and  (nvl(old_type,'1') != type or nvl(old_create_date,to_date('01.01.1899','dd.mm.yyyy')) != create_date);


Можно ли его сделать эффективнее/красивее?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
select  t1.create_date
        ,t1.type
        ,t2.create_date old_create_date
        ,t2.type  old_type
  from  t1.id = t2.id
 where  coalesce(type, old_type,'1') !=  coalesce(old_type,'1')     
   or  coalesce(create_date, old_create_date, sysdate) != coalesce(old_create_date, sysdate);
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39560967
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
decode
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561015
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Старые значения могут быть нуловыми?
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561021
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cobalt_frog
Код: plsql
1.
2.
3.
 where  type        is not null
   and  create_date is not null
   and  (nvl(old_type,'1') != type or nvl(old_create_date,to_date('01.01.1899','dd.mm.yyyy')) != create_date);



А подскажите лучше, что мы тут имеем:


Код: plsql
1.
2.
3.
 where  (type        is not null
   and  create_date is not null
   and  (nvl(old_type,'1') != type) or (nvl(old_create_date,to_date('01.01.1899','dd.mm.yyyy')) != create_date))



Или

Код: plsql
1.
2.
3.
 where  type        is not null
   and  create_date is not null
   and  ((nvl(old_type,'1') != type or nvl(old_create_date,to_date('01.01.1899','dd.mm.yyyy')) != create_date))
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561027
cobalt_frog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dshedoo,

могут, причем или оба или одно из них
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561030
cobalt_frog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Fogelcobalt_frogЯ сделал след макаром:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select  t1.create_date
        ,t1.type
        ,t2.create_date old_create_date
        ,t2.type  old_type
  from  t1.id = t2.id
 where  type        is not null
   and  create_date is not null
   and  (nvl(old_type,'1') != type or nvl(old_create_date,to_date('01.01.1899','dd.mm.yyyy')) != create_date);


Можно ли его сделать эффективнее/красивее?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
select  t1.create_date
        ,t1.type
        ,t2.create_date old_create_date
        ,t2.type  old_type
  from  t1.id = t2.id
 where  coalesce(type, old_type,'1') !=  coalesce(old_type,'1')     
   or  coalesce(create_date, old_create_date, sysdate) != coalesce(old_create_date, sysdate);



В этом случае если type is null, а create_date not null, то запись отберется.
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561034
cobalt_frog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dshedoocobalt_frog
Код: plsql
1.
2.
3.
 where  type        is not null
   and  create_date is not null
   and  (nvl(old_type,'1') != type or nvl(old_create_date,to_date('01.01.1899','dd.mm.yyyy')) != create_date);



А подскажите лучше, что мы тут имеем:


Код: plsql
1.
2.
3.
 where  (type        is not null
   and  create_date is not null
   and  (nvl(old_type,'1') != type) or (nvl(old_create_date,to_date('01.01.1899','dd.mm.yyyy')) != create_date))



Или

Код: plsql
1.
2.
3.
 where  type        is not null
   and  create_date is not null
   and  ((nvl(old_type,'1') != type or nvl(old_create_date,to_date('01.01.1899','dd.mm.yyyy')) != create_date))



окончательный вариант думаю должен быть таким:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select  t1.create_date
        ,t1.type
        ,t2.create_date old_create_date
        ,t2.type  old_type
  from  t1,t2
 where  t1.id       = t2.id
   and	type        is not null
   and  create_date is not null
   and  (nvl(old_type,'1') != type or nvl(old_create_date,to_date('01.01.1899','dd.mm.yyyy')) != create_date);



чет выглядит не очень только)
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561068
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cobalt_frogчет выглядит не очень только)

Код: 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.
SQL> with
  2   an (id,type_new) as (
  3  select 1,1 from dual union all
  4  select 2,2 from dual union all
  5  select 3,null from dual
  6  )
  7  ,bn (id,date_new) as (
  8  select 10,date '2017-11-01' from dual union all
  9  select 20,date '2017-11-02' from dual union all
 10  select 30,null from dual
 11  )
 12  ,ao (id,type_old) as (
 13  select 1,1 from dual union all
 14  select 2,3 from dual union all
 15  select 3,null from dual
 16  )
 17  ,bo (id,date_old) as (
 18  select 10,date '2017-11-01' from dual union all
 19  select 20,date '2017-11-03' from dual union all
 20  select 30,null from dual
 21  )
 22  ,t1 as (select an.id+bn.id id_new,type_new,date_new from an,bn)
 23  ,t2 as (select ao.id+bo.id id_old,type_old,date_old from ao,bo)
 24  select * from t1,t2 where t1.id_new=t2.id_old
 25  and decode(type_new,null,0,type_old,0,1)+decode(date_new,null,0,date_old,0,1)<>0
 26  /

    ID_NEW   TYPE_NEW DATE_NEW     ID_OLD   TYPE_OLD DATE_OLD
---------- ---------- -------- ---------- ---------- --------
        21          1 02.11.17         21          1 03.11.17
        12          2 01.11.17         12          3 01.11.17
        22          2 02.11.17         22          3 03.11.17
        32          2 null             32          3 null
        23 null       02.11.17         23 null       03.11.17



імхо, самое читабельное будет влоб через case

.....
stax
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561071
cobalt_frog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ну или так:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select  t1.create_date
        ,t1.type
        ,t2.create_date old_create_date
        ,t2.type  old_type
        ,case when t1.create_date is null or t1.type is null then 0
               when nvl(t2.create_date,'sysdate') != t1.create_date or nvl(t2.type,'1')!=t1.type then 1
          else 0 end ddd
  from  t1,t2
 where  t1.id       = t2.id
   and  ddd = 1
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561079
cobalt_frog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax,

как в варианте предложенном ниже?
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561081
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cobalt_frogну или так:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select  t1.create_date
        ,t1.type
        ,t2.create_date old_create_date
        ,t2.type  old_type
        ,case when t1.create_date is null or t1.type is null then 0
               when nvl(t2.create_date,'sysdate') != t1.create_date or nvl(t2.type,'1')!=t1.type then 1
          else 0 end ddd
  from  t1,t2
 where  t1.id       = t2.id
   and  ddd = 1



авторесли новое значение null, то его возвращать не надо

оба значения, или одно из двух?

....
stax
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561084
cobalt_frog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax,

одно из двух
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561128
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cobalt_frogStax,

одно из двух

я чет понял, как оба одновременно

я если уж пишу case и не ленюсь по расписывал полностью (излишне) и без nvl

типа так
Код: 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.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
SQL> ed
Wrote file afiedt.buf

  1  with
  2   an (id,type_new) as (
  3  select 1,1 from dual union all
  4  select 2,2 from dual union all
  5  select 3,null from dual
  6  )
  7  ,bn (id,date_new) as (
  8  select 10,date '2017-11-01' from dual union all
  9  select 20,date '2017-11-02' from dual union all
 10  select 30,null from dual
 11  )
 12  ,ao (id,type_old) as (
 13  select 1,1 from dual union all
 14  select 2,3 from dual union all
 15  select 3,null from dual
 16  )
 17  ,bo (id,date_old) as (
 18  select 10,date '2017-11-01' from dual union all
 19  select 20,date '2017-11-03' from dual union all
 20  select 30,null from dual
 21  )
 22  ,t1 as (select an.id+bn.id id_new,type_new,date_new from an,bn)
 23  ,t2 as (select ao.id+bo.id id_old,type_old,date_old from ao,bo)
 24  select * from t1,t2 where 1=1 --t1.id_new=t2.id_old --все варианты
 25  and case
 26   when type_new is null or date_new is null    then 0 --нові null отбрасываем
 27   when type_new=type_old and date_new=date_old then 0 --равны отбрасываем
 28   else 1                                              --не равны
 29   end = 1
 30* order by id_new,id_old
SQL> /

    ID_NEW   TYPE_NEW DATE_NEW     ID_OLD   TYPE_OLD DATE_OLD
---------- ---------- -------- ---------- ---------- --------
        11          1 01.11.17         12          3 01.11.17
        11          1 01.11.17         13 null       01.11.17
        11          1 01.11.17         21          1 03.11.17
        11          1 01.11.17         22          3 03.11.17
        11          1 01.11.17         23 null       03.11.17
        11          1 01.11.17         31          1 null
        11          1 01.11.17         32          3 null
        11          1 01.11.17         33 null       null
        12          2 01.11.17         11          1 01.11.17
        12          2 01.11.17         12          3 01.11.17
        12          2 01.11.17         13 null       01.11.17
        12          2 01.11.17         21          1 03.11.17
        12          2 01.11.17         22          3 03.11.17
        12          2 01.11.17         23 null       03.11.17
        12          2 01.11.17         31          1 null
        12          2 01.11.17         32          3 null
        12          2 01.11.17         33 null       null
        21          1 02.11.17         11          1 01.11.17
        21          1 02.11.17         12          3 01.11.17
        21          1 02.11.17         13 null       01.11.17
        21          1 02.11.17         21          1 03.11.17
        21          1 02.11.17         22          3 03.11.17
        21          1 02.11.17         23 null       03.11.17
        21          1 02.11.17         31          1 null
        21          1 02.11.17         32          3 null
        21          1 02.11.17         33 null       null
        22          2 02.11.17         11          1 01.11.17
        22          2 02.11.17         12          3 01.11.17
        22          2 02.11.17         13 null       01.11.17
        22          2 02.11.17         21          1 03.11.17
        22          2 02.11.17         22          3 03.11.17
        22          2 02.11.17         23 null       03.11.17
        22          2 02.11.17         31          1 null
        22          2 02.11.17         32          3 null
        22          2 02.11.17         33 null       null

35 rows selected.



.....
stax
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561148
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cobalt_frogFogelпропущено...

Код: plsql
1.
2.
3.
4.
5.
6.
7.
select  t1.create_date
        ,t1.type
        ,t2.create_date old_create_date
        ,t2.type  old_type
  from  t1.id = t2.id
 where  coalesce(type, old_type,'1') !=  coalesce(old_type,'1')     
   or  coalesce(create_date, old_create_date, sysdate) != coalesce(old_create_date, sysdate);



В этом случае если type is null, а create_date not null, то запись отберется.
тогда вариант проще некуда
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
select t1.create_date,
       t1.type,
       t2.create_date old_create_date,
       t2.type        old_type
  from t1
  full join t2
    on t1.id = t2.id
 where t1.create_date is not null
   and t1.type is not null
minus
select t1.create_date,
       t1.type,
       t2.create_date old_create_date,
       t2.type        old_type
  from t1
  join t2
    on t1.id = t2.id and t1.create_date = t2.create_date and
 t1.type = t2.type
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561163
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cobalt_frogStax,

одно из двух
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
select t1.create_date,
       t1.type,
       t2.create_date old_create_date,
       t2.type        old_type
  from t1
  full join t2
    on t1.id = t2.id
 where t1.create_date is not null
   or t1.type is not null
minus
select t1.create_date,
       t1.type,
       t2.create_date old_create_date,
       t2.type        old_type
  from t1
  join t2
    on t1.id = t2.id and t1.create_date = t2.create_date and
 t1.type = t2.type
...
Рейтинг: 0 / 0
Оптимизировать запрос
    #39561209
cobalt_frog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Staxcobalt_frogStax,

одно из двух

я чет понял, как оба одновременно

я если уж пишу case и не ленюсь по расписывал полностью (излишне) и без nvl

типа так
Код: 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.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
SQL> ed
Wrote file afiedt.buf

  1  with
  2   an (id,type_new) as (
  3  select 1,1 from dual union all
  4  select 2,2 from dual union all
  5  select 3,null from dual
  6  )
  7  ,bn (id,date_new) as (
  8  select 10,date '2017-11-01' from dual union all
  9  select 20,date '2017-11-02' from dual union all
 10  select 30,null from dual
 11  )
 12  ,ao (id,type_old) as (
 13  select 1,1 from dual union all
 14  select 2,3 from dual union all
 15  select 3,null from dual
 16  )
 17  ,bo (id,date_old) as (
 18  select 10,date '2017-11-01' from dual union all
 19  select 20,date '2017-11-03' from dual union all
 20  select 30,null from dual
 21  )
 22  ,t1 as (select an.id+bn.id id_new,type_new,date_new from an,bn)
 23  ,t2 as (select ao.id+bo.id id_old,type_old,date_old from ao,bo)
 24  select * from t1,t2 where 1=1 --t1.id_new=t2.id_old --все варианты
 25  and case
 26   when type_new is null or date_new is null    then 0 --нові null отбрасываем
 27   when type_new=type_old and date_new=date_old then 0 --равны отбрасываем
 28   else 1                                              --не равны
 29   end = 1
 30* order by id_new,id_old
SQL> /

    ID_NEW   TYPE_NEW DATE_NEW     ID_OLD   TYPE_OLD DATE_OLD
---------- ---------- -------- ---------- ---------- --------
        11          1 01.11.17         12          3 01.11.17
        11          1 01.11.17         13 null       01.11.17
        11          1 01.11.17         21          1 03.11.17
        11          1 01.11.17         22          3 03.11.17
        11          1 01.11.17         23 null       03.11.17
        11          1 01.11.17         31          1 null
        11          1 01.11.17         32          3 null
        11          1 01.11.17         33 null       null
        12          2 01.11.17         11          1 01.11.17
        12          2 01.11.17         12          3 01.11.17
        12          2 01.11.17         13 null       01.11.17
        12          2 01.11.17         21          1 03.11.17
        12          2 01.11.17         22          3 03.11.17
        12          2 01.11.17         23 null       03.11.17
        12          2 01.11.17         31          1 null
        12          2 01.11.17         32          3 null
        12          2 01.11.17         33 null       null
        21          1 02.11.17         11          1 01.11.17
        21          1 02.11.17         12          3 01.11.17
        21          1 02.11.17         13 null       01.11.17
        21          1 02.11.17         21          1 03.11.17
        21          1 02.11.17         22          3 03.11.17
        21          1 02.11.17         23 null       03.11.17
        21          1 02.11.17         31          1 null
        21          1 02.11.17         32          3 null
        21          1 02.11.17         33 null       null
        22          2 02.11.17         11          1 01.11.17
        22          2 02.11.17         12          3 01.11.17
        22          2 02.11.17         13 null       01.11.17
        22          2 02.11.17         21          1 03.11.17
        22          2 02.11.17         22          3 03.11.17
        22          2 02.11.17         23 null       03.11.17
        22          2 02.11.17         31          1 null
        22          2 02.11.17         32          3 null
        22          2 02.11.17         33 null       null

35 rows selected.



.....
stax

согласен, условие на nvl лишнее и блок кейс лучше вынести в where, чтобы для всех строк он не выполнялся. Большое спасибо.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Оптимизировать запрос
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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