Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Group by / 13 сообщений из 13, страница 1 из 1
29.05.2020, 12:56
    #39964022
kvitnitskiy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
Доброго времени суток уважаемые.
есть запрос с группировкой. Как можно группировать, что бы в group by не прописывать снова то же что и в select ?

Код: 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.
   SELECT
o.SHIPMENT_NUMBER,
regexp_replace(listagg(c.CSTNAM,';') within group(order by c.CSTNAM),'([^;]+)(;\1)?+','\1') as CSTNAM,
min(o.APPT_DATE) APPT_DATE,
       CASE
           WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
AND o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20:00:00'), 'DD.MM.YY hh24:mi:ss')
           THEN CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 08-20')
           WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20:00:00'), 'DD.MM.YY hh24:mi:ss')
AND o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE + 1, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
           THEN CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20-08')
           ELSE CONCAT(TO_CHAR(o.APPT_DATE - 1, 'DD.MM.YY'), ' 20-08')
       END AS "CalAppptShift",
       CASE
           WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
AND o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20:00:00'), 'DD.MM.YY hh24:mi:ss')
           THEN TO_CHAR(o.APPT_DATE, 'DD.MM.YY')
           WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20:00:00'), 'DD.MM.YY hh24:mi:ss')
AND o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE + 1, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
           THEN TO_CHAR(o.APPT_DATE, 'DD.MM.YY')
           ELSE TO_CHAR(o.APPT_DATE - 1, 'DD.MM.YY')
       END AS "CalcApptDate"
FROM
ORDER_SHIPMENT o
INNER JOIN CUSTMR c ON o.PLN_NUMBER = c.PLNNUM
group BY
o.SHIPMENT_NUMBER,  
       CASE
           WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
AND o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20:00:00'), 'DD.MM.YY hh24:mi:ss')
           THEN CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 08-20')
           WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20:00:00'), 'DD.MM.YY hh24:mi:ss')
AND o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE + 1, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
           THEN CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20-08')
           ELSE CONCAT(TO_CHAR(o.APPT_DATE - 1, 'DD.MM.YY'), ' 20-08')
       END,
       CASE
           WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
AND o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20:00:00'), 'DD.MM.YY hh24:mi:ss')
           THEN TO_CHAR(o.APPT_DATE, 'DD.MM.YY')
           WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20:00:00'), 'DD.MM.YY hh24:mi:ss')
AND o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE + 1, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
           THEN TO_CHAR(o.APPT_DATE, 'DD.MM.YY')
           ELSE TO_CHAR(o.APPT_DATE - 1, 'DD.MM.YY')
       END

...
Рейтинг: 0 / 0
29.05.2020, 14:46
    #39964097
MakeSure
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
Вижу пару вариантов:
1. В подзапрос добавьте расчет один раз, группировку на уровень выше;
2. Создать функцию, которая будет возвращать Вам значение по входной переменной, тогда не будет так громоздко.

Но что бы посоветовал, это вчитать в запрос и понять что там происходит. Можно и покороче все написать.

Например, вот эта часть не имеет смысла вовсе:
Код: plsql
1.
o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE + 1, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')



Еще посмотрите в сторону EXTRACT функции. Никакого смысла переводить дату в строку, а потом опять в дату в Вашем случае нет.
...
Рейтинг: 0 / 0
29.05.2020, 15:01
    #39964111
oragraf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
kvitnitskiy
Код: plsql
1.
         WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')

ТС, про арифметику дат почитай
...
Рейтинг: 0 / 0
29.05.2020, 15:51
    #39964144
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
kvitnitskiy,

with/подзапрос
group by "CalAppptShift",...

ps
вопрос достаточно часто всплывает, почему б не сделать как в order by

.....
stax
...
Рейтинг: 0 / 0
29.05.2020, 16:07
    #39964157
kvitnitskiy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
oragraf,
ЧТо не так ? мне к дате надо "приклеить" 08:00:00
...
Рейтинг: 0 / 0
29.05.2020, 16:13
    #39964160
kvitnitskiy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
MakeSure,

авторНапример, вот эта часть не имеет смысла вовсе:

Почему ?
мне надо что бы датавремя которое идет с 20:00 до 08:00 возвращало как одну дату ( до 00:00) и это работает.
рабоачая смена длится 08:00 - 20:00 20:00 -08:00 , мне в двльнейшем нужна групп ировка данных по сменам как раз. и этот вариант прекрасно работает.
...
Рейтинг: 0 / 0
29.05.2020, 16:19
    #39964162
kvitnitskiy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
MakeSure,

за авторЕще посмотрите в сторону EXTRACT спасибо.
Хотя не понятно как раотает.
в хепе пишет что
авторЕсли же я напишу так: year_month - то будет извлечен год и месяц (слитно, без разделителя).
на практике же получаю ошибку [Err] ORA-00907: missing right parenthesis

Код: plsql
1.
2.
select  EXTRACT(year_day from ORDER_SHIPMENT.APPT_DATE)
from ORDER_SHIPMENT
...
Рейтинг: 0 / 0
29.05.2020, 16:22
    #39964164
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
kvitnitskiy

Почему ?

что надо понятно

o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE + 1 , 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
всегда True

Код: 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.
SQL> ed
Wrote file afiedt.buf

  1  with o(APPT_DATE) as (
  2  select to_date ('29.05.2020 03:00:00','dd.mm,yyyy hh24:mi:ss') from dual union all
  3  select to_date ('29.05.2020 13:00:00','dd.mm,yyyy hh24:mi:ss') from dual union all
  4  select to_date ('29.05.2020 23:00:00','dd.mm,yyyy hh24:mi:ss') from dual
  5  )
  6  select APPT_DATE,
  7         CASE
  8             WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
  9  AND o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20:00:00'), 'DD.MM.YY hh24:mi:ss')
 10             THEN CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 08-20')
 11             WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20:00:00'), 'DD.MM.YY hh24:mi:ss')
 12  AND o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE + 1, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
 13             THEN CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20-08 1')
 14             ELSE CONCAT(TO_CHAR(o.APPT_DATE - 1, 'DD.MM.YY'), ' 20-08 2')
 15         END AS "CalAppptShift"
 16  ,CONCAT(TO_CHAR(o.APPT_DATE + 1, 'DD.MM.YY'), ' 08:00:00') c
 17* from o
SQL> /

APPT_DATE           CalAppptShift    C
------------------- ---------------- -----------------
29.05.2020 03:00:00 28.05.20 20-08 2 30.05.20 08:00:00
29.05.2020 13:00:00 29.05.20 08-20   30.05.20 08:00:00
29.05.2020 23:00:00 29.05.20 20-08 1 30.05.20 08:00:00


....
stax
...
Рейтинг: 0 / 0
29.05.2020, 16:28
    #39964165
MakeSure
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
upd: выше уже ответили :)

kvitnitskiy,

Посмотрим на этот кейс:
Код: plsql
1.
2.
WHEN o.APPT_DATE >= to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 20:00:00'), 'DD.MM.YY hh24:mi:ss')
     AND o.APPT_DATE <= to_date(CONCAT(TO_CHAR(o.APPT_DATE + 1, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')



Первое условие по смыслу правильное (хотя разберитесь куда должны входить 20:00 - в первый кейс или во второй).
И это условие нам говорит, если o.APPT_DATE больше либо равно 20:00 того же дня.

Второе условие пытается наложить дополнительное ограничение:
* o.APPT_DATE должно быть меньше чем 8 утра следующего за этим же o.APPT_DATE днем.
Как бы не вертели математику, но: x < x+1 , поэтому смысла никакого в этом условии нет.
...
Рейтинг: 0 / 0
29.05.2020, 16:31
    #39964167
kvitnitskiy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
Тем не менее это рабоатет
...
Рейтинг: 0 / 0
29.05.2020, 16:44
    #39964173
kvitnitskiy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
MakeSure
upd: выше уже ответили :)

(хотя разберитесь куда должны входить 20:00 - в первый кейс или во второй).


Да это я тупанул, спасибо за замечание .
...
Рейтинг: 0 / 0
31.05.2020, 13:39
    #39964654
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
Stax
Код: plsql
1.
2.
to_date(CONCAT(TO_CHAR(o.APPT_DATE, 'DD.MM.YY'), ' 08:00:00'), 'DD.MM.YY hh24:mi:ss')
 


Код: plsql
1.
trunc(o.APPT_DATE,'DD') + 8/24
...
Рейтинг: 0 / 0
31.05.2020, 14:20
    #39964670
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Group by
andrey_anonymous,

ето понятно

замечание что условие лишнее (and true)

ps
я даж 'DD' ленился набирать

.....
stax
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Group by / 13 сообщений из 13, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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