как мы можем сгруппировать 5 вечера вчера до 5 вечера сегодня записи на сегодняшнюю дату - PullRequest
1 голос
/ 22 октября 2019

таблица оракулов

id  timestamp                status
1  2019-10-20 12:34:56.000   approved
1  2019-10-22 12:34:56.000   approved
2  2019-10-20 17:34:56.000   approved
2  2019-10-21 12:34:56.000   approved
3  2019-10-23 18:10:10.000   mod_in_ip
3  2019-10-24 11:10:10.000   approved
3  2019-10-24 12:10:10.000   approved
4  2019-10-25 12:10:10.000   approved
4  2019-10-25 18:10:10.000   approved

Я хочу пометить идентификаторы как новые или отредактированные . проблема с записями с 5 вечера до 5 вечера считается рабочий период т.е.
'2019-10-25 17:00:00' до '2019-10-26 17:00:00' будетсчитается рабочим периодом
или вчерашние 17:00 до сегодняшнего 17:00 рабочего периода.

Например: запись id со вчерашней записью в 18:00 и сегодняшней записью в 11:00 должна быть помечена как новаяесли вы посмотрите на таблицу и ожидаемый результат, вы можете получить идею

ожидаемый результат / результат должен быть

1 edited
2 new
3 new
4 edited

, изначально я пытался это сделать, но это не помогло решить вышеточка

select id,
case
when count(id)<=1 then 'New' 
else 'Edited' End AS prefix 
from(select id,status ,trunc(timestamp) from table 
where 
status='approved' and id in (1,2,3,4)
group by id,status,trunc(timestamp))
group by id

результат

1 Edited
2 Edited
3 new
4 new

, но ожидаемый результат

1 edited
2 new
3 new
4 edited

Я ищу решения, такие как Внутренние запросы группируют записи с 17:00 до 17:00 , так что внешний запрос может работать нормально или также возможно совершенно другое решение

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=abd90416004000043c85316423d64b17

Ответы [ 2 ]

1 голос
/ 22 октября 2019

Если вы хотите трактовать 17:00 - 17:00 как «тот же» день, легко сместить дату Oracle вперед или назад с долями дня (например, 5:00 можно сдвинуть на 7 часов вперед, чтобы начать начало«следующий» день)

SQL> create table ora_table (id number, time_data timestamp, status varchar2(30));

Table created.

SQL> insert into ora_table values (1  , to_timestamp('2019-10-20 12:34:56.000', 'yyyy-mm-dd hh24:mi:ss.ff'), 'approved');

1 row created.

SQL> insert into ora_table values (1  , to_timestamp('2019-10-22 12:34:56.000', 'yyyy-mm-dd hh24:mi:ss.ff'), 'approved');

1 row created.

SQL> insert into ora_table values (2  , to_timestamp('2019-10-20 17:34:56.000', 'yyyy-mm-dd hh24:mi:ss.ff'), 'approved');

1 row created.

SQL> insert into ora_table values (2  , to_timestamp('2019-10-21 12:34:56.000', 'yyyy-mm-dd hh24:mi:ss.ff'), 'approved');

1 row created.

SQL> insert into ora_table values (3  , to_timestamp('2019-10-23 18:10:10.000', 'yyyy-mm-dd hh24:mi:ss.ff'), 'mod_in_ip');

1 row created.

SQL> insert into ora_table values (3  , to_timestamp('2019-10-24 11:10:10.000', 'yyyy-mm-dd hh24:mi:ss.ff'), 'approved');

1 row created.

SQL> insert into ora_table values (3  , to_timestamp('2019-10-24 12:10:10.000', 'yyyy-mm-dd hh24:mi:ss.ff'), 'approved');

1 row created.

SQL> insert into ora_table values (4  , to_timestamp('2019-10-25 12:10:10.000', 'yyyy-mm-dd hh24:mi:ss.ff'), 'approved');

1 row created.

SQL> insert into ora_table values (4  , to_timestamp('2019-10-25 18:10:10.000', 'yyyy-mm-dd hh24:mi:ss.ff'), 'approved');

1 row created.

SQL>
SQL> select id, time_data, trunc(time_data) true_date, trunc(time_data+7/24) mapped_date
  2  from ora_table;

        ID TIME_DATA                          TRUE_DATE MAPPED_DA
---------- ---------------------------------- --------- ---------
         1 20-OCT-19 12.34.56.000000 PM       20-OCT-19 20-OCT-19
         1 22-OCT-19 12.34.56.000000 PM       22-OCT-19 22-OCT-19
         2 20-OCT-19 05.34.56.000000 PM       20-OCT-19 21-OCT-19 <===
         2 21-OCT-19 12.34.56.000000 PM       21-OCT-19 21-OCT-19
         3 23-OCT-19 06.10.10.000000 PM       23-OCT-19 24-OCT-19 <===
         3 24-OCT-19 11.10.10.000000 AM       24-OCT-19 24-OCT-19
         3 24-OCT-19 12.10.10.000000 PM       24-OCT-19 24-OCT-19
         4 25-OCT-19 12.10.10.000000 PM       25-OCT-19 25-OCT-19
         4 25-OCT-19 06.10.10.000000 PM       25-OCT-19 26-OCT-19

9 rows selected.
0 голосов
/ 22 октября 2019

Это должно дать вам то, что вы ищете:

WITH cte(id, ts, NewCutoff, Row_Num) AS (
  select 
    id, 
    ts, 
    MIN(
      trunc(ts) + 
      CASE 
        WHEN EXTRACT(HOUR FROM ts) < 17 THEN INTERVAL '00 17' DAY TO HOUR
        ELSE INTERVAL '01 17' DAY TO HOUR -- If time is after 5pm, add an extra day
      END
    ) OVER(PARTITION BY id) AS NewCutoff, -- Determine cut-off TS for "new" entries
    ROW_NUMBER() OVER(
      PARTITION BY id ORDER BY ts DESC
    ) AS Row_Num -- Order entries by date within "id" group
  FROM mytable
)
SELECT id, CASE WHEN ts < NewCutoff THEN 'new' ELSE 'edited' END AS prefix
FROM cte
WHERE Row_Num = 1 -- Only look at latest entry per id
;

Возможно, вам придется проверить конечные условия - то есть, как обработать значение ts ровно с 5 вечера.

1006 * SQL Fiddle
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...