powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Group by
13 сообщений из 13, страница 1 из 1
Group by
    #39964022
kvitnitskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток уважаемые.
есть запрос с группировкой. Как можно группировать, что бы в 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
Group by
    #39964097
MakeSure
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вижу пару вариантов:
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
Group by
    #39964111
oragraf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Group by
    #39964144
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kvitnitskiy,

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

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

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

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

Почему ?
мне надо что бы датавремя которое идет с 20:00 до 08:00 возвращало как одну дату ( до 00:00) и это работает.
рабоачая смена длится 08:00 - 20:00 20:00 -08:00 , мне в двльнейшем нужна групп ировка данных по сменам как раз. и этот вариант прекрасно работает.
...
Рейтинг: 0 / 0
Group by
    #39964162
kvitnitskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
Group by
    #39964164
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Group by
    #39964165
MakeSure
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Group by
    #39964167
kvitnitskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Тем не менее это рабоатет
...
Рейтинг: 0 / 0
Group by
    #39964173
kvitnitskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MakeSure
upd: выше уже ответили :)

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


Да это я тупанул, спасибо за замечание .
...
Рейтинг: 0 / 0
Group by
    #39964654
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Group by
    #39964670
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

ето понятно

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

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

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


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