Подсчет данных за день между двумя датами - PullRequest
0 голосов
/ 14 февраля 2020

Привет, я пытаюсь подсчитать общее количество поздних замечаний за день между двумя датами, введенными пользователем.

например:

ID  NAME    DATE_TIME         REMARKS
1   Aa  2020-01-18 09:57:56     LATE
2   Aa  2020-01-18 10:57:56     LATE
3   Aa  2020-01-19 06:52:56    
4   Aa  2020-01-19 09:57:56     LATE
5   Aa  2020-01-19 09:57:56     LATE
6   Aa  2020-01-21 09:57:56     Late

Ожидаемый результат.

NAME     DATE          count
Aa     2020-01-18         2
Aa     2020-01-19         2
Aa     2020-01-20         0
Aa     2020-01-21         1

Тип данных DATE_TIME: varhcar2

Это моя попытка, но я не знаю, как этого добиться.

Select Count(REMARKS) countBT from TBLACCESSLOGS WHERE To_date(DATE_TIME,'YYYY-MM-DD') between To_date('2020-02-18','YYYY-MM-DD') and To_date('2020-02-20','YYYY-MM-DD')

и я получаю ошибку date format picture ends before converting entire input string, указывающую на DATE_TIME как я выполняю.

Надеюсь, кто-нибудь поможет мне с этим. Заранее спасибо

Ответы [ 3 ]

3 голосов
/ 14 февраля 2020

Поскольку существует вероятность того, что в диапазоне, который вы ищете, могут отсутствовать даты, вам нужно создать запись для каждой даты в этом диапазоне. Вы объединяете эти даты со своей таблицей, считая количество замечаний в колонке.

with date_parms as 
     (select to_date('&Start_Date','yyyy-mm-dd') start_date 
           , to_date('&End_Date','yyyy-mm-dd') end_date
        from dual
     ) 
    , date_list as
      (select start_date+lev-1 t_date 
         from date_parms
            , ( select level lev 
                  from dual 
                connect by level <= (select end_date - start_date + 1   
                                       from date_parms
                                    )
               ) 
       )  
select t_date "Date"
     , name
     , count(*) "Num Late"
  from date_list  dl
  left join lates l  on trunc(l.date_time) = dl.t_date and lower(l.remark) = 'late' 
 where 1=1 --lower(l.remark) = 'late'
 group by trunc(t_time), name; 

Примечание. После того, как начальные параметры (даты начала и окончания) преобразованы в строки и даты, дальнейшие манипуляции со строками даты не требуются.

1 голос
/ 14 февраля 2020

полностью отредактировано; это многошаговый процесс, действительно важный SQL logi c находится в «THE_GOODS». Поколение дней в «Днях», и я взял это отсюда: https://www.zetetic.net/blog/2009/2/12/generating-a-sequential-date-series-in-oracle.html - я не понимаю это намного больше, чем ctl-c / ctl-v. «PERMS» делает перестановку дат / имен, затем она присоединяется к THE_GOODS слева, чтобы получить количество. Таким образом, для каждой комбинации пользователя и дат в диапазоне вы получаете одну строку и счет от THE_GOODS, или ноль, если нет подходящей строки.

, чтобы поиграть с ней: http://sqlfiddle.com/#! 4/42618 / 8

 WITH DAYS AS 
 (SELECT TO_CHAR(TRUNC(TO_DATE('01-JAN-2020') + ROWNUM - 1, 'DD'), 'YYYY-MM-DD') AS ADAY
 FROM (
   SELECT ROWNUM FROM (
 SELECT 1 FROM DUAL
 CONNECT BY LEVEL <= (TO_DATE('08-JAN-2020') - TO_DATE('01-JAN-2020'))
   )
 )
 ),
 THE_GOODS AS (
   select name, to_char(DATE_TIME, 'YYYY-MM-DD') AS ADAY, count(*) AS HOW_MANY
 from TBLACCESSLOGS
 where trunc(DATE_TIME, 'DD') between to_date('2020-01-01', 'YYYY-MM-DD')
 and to_date('2020-01-05', 'YYYY-MM-DD')
 and remarks = 'LATE'
 group by name, to_char(DATE_TIME, 'YYYY-MM-DD')
   )
 ,
 PERMS AS (
 SELECT DISTINCT DAYS.ADAY,  THE_GOODS.NAME
 FROM DAYS 
   CROSS JOIN
   THE_GOODS
  )
   SELECT p.NAME, p.ADAY, COALESCE(g.HOW_MANY, 0) AS HOWMANY
   FROM PERMS p
   LEFT JOIN THE_GOODS g
 on p.ADAY = g.ADAY
 and p.NAME = g.NAME
   ORDER BY p.ADAY, g.NAME
0 голосов
/ 14 февраля 2020

Попробуйте это ..

    SQL> select * from late_remarks;

        ID NAME DATE_TIME             REMARKS
        -- --   -------------------   ----
        1  Aa   2020-01-18 09:57:56   LATE
        2  Aa   2020-01-18 10:57:56   LATE
        3  Aa   2020-01-19 06:52:56
        4  Aa   2020-01-19 09:57:56   LATE
        5  Aa   2020-01-19 09:57:56   LATE
        6  Aa   2020-01-21 09:57:56   LATE

    6 rows selected.



    SQL> with dates as (
      2      select to_date('17-01-2020', 'DD-MM-YYYY') + level "DATE"
      3      from dual
      4      connect by level <= (to_date('21-01-2020', 'DD-MM-YYYY') - to_date('17-01-2020', 'DD-MM-YYYY'))
      5      )
      6  select 'Aa' name, d."DATE", count(lr.remarks) count from dates d
      7      left outer join late_remarks lr
      8          on d."DATE" = trunc(to_timestamp (lr.date_time, 'YYYY-MM-DD HH24:MI:SS'))
      9      group by d."DATE"
     10      order by d."DATE";

    NAME DATE           COUNT
    --   --------- ----------
    Aa   18-JAN-20          2
    Aa   19-JAN-20          2
    Aa   20-JAN-20          0
    Aa   21-JAN-20          1

.. при условии, что имя будет постоянным

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