oracle sql compare times where > 1 on single work date - sql

The not like operator is not suitable for comparing values where the number of values is > 1 on a single work date. In the example below the records in the first 2 rows are a match (bold=bold, italic=italic) and should NOT appear in the output. The issue is caused by the ‘not like’ operator looping.
i have simplified the code as follows:
SELECT e.EMP_NAME AS APS,
TO_CHAR (ws.WRKS_WORK_DATE, 'dd.mm.yyyy') AS Work_Date,
TO_CHAR ( (wd.WRKD_START_TIME), 'hh24:mi') AS Leave_Start_Time,
TO_CHAR ( (wd.WRKD_end_TIME), 'hh24:mi') AS Leave_End_Time,
TO_CHAR (sb.SHFTBRK_DEF_START, 'hh24:mi') AS shift_brk_Start,
TO_CHAR (sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES + 1) * .000694,
'hh24:mi')
AS shift_brk_end
FROM work.WORK_SUMMARY ws,
work.employee e,
work.work_detail wd,
work.TIME_CODE tc,
work.shift s,
work.shift_break sb,
work.EMPLOYEE_SCHEDULE es
WHERE ws.emp_id = e.emp_id
AND wd.WRKD_MINUTES < s.SHFT_VAL1 ---sum workd minutes less than shift id actual shift minutes
AND ws.WRKS_WORK_DATE BETWEEN '09-Jul-2013' AND '09-Jul-2013'
AND wd.WRKS_ID = ws.WRKS_ID
AND tc.TCODE_name IN
('COMP', 'SL COMP PEN', 'ARB','LUC',
'CMF', 'MREP', 'WSSL', 'RL',
'CBK', 'JUR', 'LSL', 'LSLT',
'LWPNC', 'LWPS', 'LWPTC', 'LWPU',
'LWOP', 'ML', 'MLHP', 'NWPTC',
'PAT', 'PL', 'SD', 'MSP',
'SUS', 'SUSW', 'WIT', 'CMPA',
'ABC', 'ABN', 'BER', 'COM',
'COMWP', 'IS', 'EXL', 'LFI',
'MER', 'NCD', 'PCLC', 'PCLS',
'PSLC', 'PSLN', 'PSLW', 'PSWO',
'PSLP', 'PURL', 'STU', 'UA',
'GRTW')
AND wd.TCODE_ID = tc.TCODE_ID
AND ws.PAYGRP_ID IN ('10023')
AND ws.WRKS_AUTHORIZED = 'Y'
AND e.EMP_TERMINATION_DATE >= CURRENT_DATE
--and e.emp_name in('1100376801','1100590701')
AND ws.WRKS_WORK_DATE = es.WORK_DATE
AND ws.emp_id = es.emp_id
AND ws.shft_id = es.EMPSKD_ACT_SHIFT_ID
AND es.EMPSKD_ACT_SHIFT_ID = s.SHFT_ID
AND s.SHFT_ID = sb.SHFT_ID
AND ( ( TO_CHAR (sb.SHFTBRK_DEF_START, 'hh24:mi') <=
TO_CHAR ( (wd.WRKD_START_TIME), 'hh24:mi')
AND TO_CHAR (
sb.SHFTBRK_DEF_START
+ (sb.SHFTBRK_MINUTES + 1) * .000694,
'hh24:mi') >
TO_CHAR ( (wd.WRKD_START_TIME), 'hh24:mi'))
OR ( TO_CHAR (sb.SHFTBRK_DEF_START, 'hh24:mi') <
TO_CHAR ( (wd.WRKD_end_TIME), 'hh24:mi')
AND TO_CHAR (
sb.SHFTBRK_DEF_START
+ (sb.SHFTBRK_MINUTES + 1) * .000694,
'hh24:mi') > TO_CHAR ( (wd.WRKD_end_TIME), 'hh24:mi'))
OR ( TO_CHAR (sb.SHFTBRK_DEF_START, 'hh24:mi') >
TO_CHAR ( (wd.WRKD_START_TIME), 'hh24:mi')
AND TO_CHAR (
sb.SHFTBRK_DEF_START
+ (sb.SHFTBRK_MINUTES + 1) * .000694,
'hh24:mi') < TO_CHAR ( (wd.WRKD_end_TIME), 'hh24:mi'))
OR ( TO_CHAR (sb.SHFTBRK_DEF_START, 'hh24:mi') =
TO_CHAR ( (wd.WRKD_end_TIME), 'hh24:mi')
AND TO_CHAR (
sb.SHFTBRK_DEF_START
+ (sb.SHFTBRK_MINUTES + 1) * .000694,
'hh24:mi') = TO_CHAR ( (wd.WRKD_end_TIME), 'hh24:mi')))
GROUP BY e.EMP_NAME,
ws.WRKS_WORK_DATE,
wd.WRKD_end_TIME,
wd.WRKD_START_TIME,
sb.SHFTBRK_DEF_START,
TO_CHAR (sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES + 1) * .000694,
'hh24:mi');
Result:
APS WORK_DATE LEAVE_START_TIME LEAVE_END_TIME SHIFT_BRK_START SHIFT_BRK_END
-------------------------------------------------------------------------------------
40151401 09.07.2013 10:00 13:00 10:30 11:00
40200001 09.07.2013 09:00 12:51 10:00 10:30
40447701 09.07.2013 09:30 14:15 10:00 10:30
40492101 09.07.2013 15:00 20:10 16:00 16:30
61037301 09.07.2013 10:35 14:15 11:00 11:30
64173401 09.07.2013 09:30 14:15 10:00 10:30
The issue is that i am expecting to see a record for employee 1100376801.
The reason I can't see the record is because the times for the missing record fall over midnight, i.e 00:51. How can i format the 'datetime' fields differently so that times over midnight are picked up, i.e. where the SHIFT_BRK_START and SHIFT_BRK_END times span or fall within the LEAVE_START_TIME and LEAVE_END_TIME.
Expected result: in addition to the results returned above i should also see the following record:
APS WORK_DATE LEAVE_START_TIME LEAVE_END_TIME SHIFT_BRK_START SHIFT_BRK_END
-------------------------------------------------------------------------------------
11003701 09.07.2013 20:00 **0:51** 19:30 19:45
RESOLUTION:
and
(
(to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') < (wd.WRKD_START_TIME) and
to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') > (wd.WRKD_start_TIME))---1
OR(to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') =(wd.WRKD_START_TIME) and
to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') = (wd.WRKD_end_TIME))--4
OR(to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') =(wd.WRKD_START_TIME) and
to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') > (wd.WRKD_end_TIME))---5
OR(to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') =(wd.WRKD_START_TIME) and
to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') <(wd.WRKD_end_TIME))---5
OR (to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') > (wd.WRKD_START_TIME) and
to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') <= (wd.WRKD_end_TIME))---3
OR (to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') > (wd.WRKD_START_TIME) and
to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') < (wd.WRKD_end_TIME) and
to_date(to_char(wd.WRKD_START_TIME, 'dd.mm.yyyy') || '' || to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, 'hh24:mi'), 'dd.mm.yyyy hh24:mi') > (wd.WRKD_end_TIME))---2
)

Its still not clear about your requirement and data
Here are some points to check:
check the two below queries with 'ALTER SESSION NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI:SS';
(e.EMP_NAME || '_' || TO_CHAR(ws.WRKS_WORK_DATE,'dd.mm.yyyy') || '_' ||to_char(min(wd.WRKD_START_TIME), 'HH24:MI')|| '_' ||to_char(max(wd.WRKD_end_TIME), 'HH24:MI')) as test
(e.EMP_NAME || '_' || TO_CHAR(ws.WRKS_WORK_DATE,'dd.mm.yyyy') || '_' ||to_char(sb.SHFTBRK_DEF_START,'HH24:MI')|| '_' ||to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, 'HH24:MI')) as test
The condition for outermost query might not work as you expected,
not like operator will fail as your inner query for the column test is different.
where a_emp_break.test not like b_shift_break.test
and a_emp_break.APS=b_shift_break.APS
and a_emp_break.Work_Date = b_shift_break.Work_Date
you didn't mention the date you needed anywhere.
updating
check with the below outer query again:
TO_CHAR (sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES + 1) * .000694, 'hh24:mi') AS shift_brk_end
AND ws.WRKS_WORK_DATE BETWEEN '09-Jul-2013' AND '09-Jul-2013' check the above includes the desired ids.
check again with the conditions with the to_date() funcition that accurating with < and > symbols.
Thanks.

Related

ORA-01756: quoted string not properly terminated, a part of my query it's failing

select 'BETWEEN TO_DATE(''' || to_char(CURRENT_DATE, 'dd/MM/yyyy 00:00:00') || ''', ''DD/MM/YYYY HH24:MI:SS'') AND TO_DATE(''' || to_char(CURRENT_DATE + 1, 'dd/MM/yyyy 00:00:00')
Is there something bad in this Query? It's not the full query it's just a part of it. I'ts throwing this error:
ORA-01756: quoted string not properly terminated
Use the q-quoting mechanism.
By the way, your code can be simplified to
select q'[between trunc(current_date) and trunc(current_date + 1)]' result
from dual;
No need to to_char and then to_date current_date; it already is DATE datatype, just remove (truncate to midnight) time component.
By the way #2, format mask you used is wrong; should be dd/mm/yyyy hh24:mi:ss (not dd/mm/yyyy 00:00:00)
If you insist (though, I don't know why would you), then
select q'[between to_date(to_char(current_date , 'dd/mm/yyyy hh24:mi:ss'), 'dd/mm/yyyy hh24:mi:ss')]' ||
q'[ and to_date(to_char(current_date + 1, 'dd/mm/yyyy hh24:mi:ss'), 'dd/mm/yyyy hh24:mi:ss')]'
as result
from dual;
Does it work? Yes:
SQL> select q'[between to_date(to_char(current_date , 'dd/mm/yyyy hh24:mi:ss'), 'dd/mm/yyyy hh24:mi:ss')]' ||
2 q'[ and to_date(to_char(current_date + 1, 'dd/mm/yyyy hh24:mi:ss'), 'dd/mm/yyyy hh24:mi:ss')]'
3 as result
4 from dual;
RESULT
--------------------------------------------------------------------------------
between to_date(to_char(current_date , 'dd/mm/yyyy hh24:mi:ss'), 'dd/mm/yyyy
hh24:mi:ss') and to_date(to_char(current_date + 1, 'dd/mm/yyyy hh24:mi:ss'),
'dd/mm/yyyy hh24:mi:ss')
SQL>
Now copy/paste the result into another query and verify it:
SQL> select *
2 from dual
3 where sysdate
4 -- this is the "result":
5 between to_date(to_char(current_date , 'dd/mm/yyyy hh24:mi:ss'), 'dd/mm/yyyy hh24:mi:ss') and to_date(to_char(current_date + 1, 'dd/mm/yyyy hh24:mi:ss'), 'dd/mm/yyyy hh24:mi:ss')
6 ;
D
-
X
SQL>
Didn't fail, eh?

ORA-01722: invalid number on subquery

Hi i'm trying to execute my query and unfortunately trows me wih error of ORA-01722: invalid number
SELECT L.NEVENTLOGIDN, LPAD (nuserid, 6, '0') nuserid, u.susername,
TO_CHAR (TO_DATE ('1970-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') + ( (ndatetime) / (60 * 60 * 24)), 'YYYY-MM-DD HH24:MI:SS')
date_time, l.nreaderidn, r.sname,
CASE WHEN l.nreaderidn IN (SELECT GETREADERSBYFUNC('OUT', 'LOCKER') devices FROM dual ) THEN 'O'
WHEN l.nreaderidn IN (SELECT GETREADERSBYFUNC('IN', 'LOCKER') devices FROM dual ) THEN 'I' END logtype
FROM TB_EVENT_LOG l, TB_READER r, TB_USER u
WHERE
l.nreaderidn IN ( SELECT GETREADERSBYDESC('LOCKER') devices FROM dual)
AND NDATETIME >= ((TO_DATE ('2020-01-27' || ' 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM') ) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60
AND ndatetime <= ((TO_DATE ('2020-01-28' || ' 12:00:00 PM', 'YYYY-MM-DD HH:MI:SS PM') ) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60
AND l.nuserid = u.suserid
AND l.nreaderidn = r.nreaderidn
ORDER BY 2, 4
I think the reason of error is this below.
1
CASE WHEN l.nreaderidn IN (SELECT GETREADERSBYFUNC('OUT', 'LOCKER') devices FROM dual ) THEN 'O'
sample data of GetReaderbyfunc
'544381428','544381436','544381433','544381424','544381043'
2
WHEN l.nreaderidn IN (SELECT GETREADERSBYFUNC('IN', 'LOCKER') devices FROM dual ) THEN 'I' END logtype
3
WHERE
l.nreaderidn IN ( SELECT GETREADERSBYDESC('LOCKER') devices FROM dual)
SELECT GETREADERSBYFUNC('OUT', 'LOCKER') devices FROM dual
result is below
'544381428','544381436','544381433','544381424','544381043'
because the nreaderidn is a number type but when i put the result of it like bellow it is working
SELECT GETREADERSBYDESC('LOCKER') devices FROM dual
result is bellow
'544381050','544381441','544381428','544381436','544381431','544381064','544381433','544381435','544381424','544381043'
WHERE
l.nreaderidn IN ( '544381428','544381436','544381433','544381424','544381043')
functions
getreadersbyfunc (p_func VARCHAR2, p_desc VARCHAR2)
RETURN VARCHAR2
IS
retVal VARCHAR2(1024);
BEGIN
for cur_rec in (SELECT nreaderidn FROM tb_reader where sdescription = p_desc and upper(sname) like '%' || upper(p_func) || '%')
loop
if retVal is NULL then
retVal := '''' || cur_rec.nreaderidn || '''';
else
retVal := retVal || ',''' || cur_rec.nreaderidn || '''';
end if;
end loop;
return retVal;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN OTHERS THEN
RAISE;
getreadersbydesc (p_description VARCHAR2)
RETURN VARCHAR2
IS
retVal VARCHAR2(1024);
BEGIN
for cur_rec in (SELECT nreaderidn FROM tb_reader where sdescription = p_description)
loop
if retVal is NULL then
retVal := '''' || cur_rec.nreaderidn || '''';
else
retVal := retVal || ',''' || cur_rec.nreaderidn || '''';
end if;
end loop;
return retVal;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN OTHERS THEN
RAISE;
END;
I'm not allowed to change the data type of nreaderidn and to modify the oracle function.
Is There a way to solve this?
Thank you in advance
Your function returns a comma separated list of numbers, which needs to be split.
Try th
Eg:
SELECT
regexp_substr(GETREADERSBYFUNC('OUT', 'LOCKER'), '[^,]+', 1, level)
FROM dual
connect by
regexp_substr(GETREADERSBYFUNC('OUT', 'LOCKER'), '[^,]+', 1, level) is not null
Your query would then look like:
SELECT L.NEVENTLOGIDN, LPAD (nuserid, 6, '0') nuserid, u.susername,
TO_CHAR (TO_DATE ('1970-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') + ( (ndatetime) / (60 * 60 * 24)), 'YYYY-MM-DD HH24:MI:SS')
date_time, l.nreaderidn, r.sname,
CASE WHEN l.nreaderidn IN (SELECT
regexp_substr(GETREADERSBYFUNC('OUT', 'LOCKER'), '[^,]+', 1, level) FROM dual
connect by regexp_substr(GETREADERSBYFUNC('OUT', 'LOCKER'), '[^,]+', 1, level) is not null ) THEN 'O'
WHEN l.nreaderidn IN (SELECT
regexp_substr(GETREADERSBYFUNC('IN', 'LOCKER'), '[^,]+', 1, level) FROM dual
connect by regexp_substr(GETREADERSBYFUNC('IN', 'LOCKER'), '[^,]+', 1, level) is not null) THEN 'I' END logtype
FROM TB_EVENT_LOG l, TB_READER r, TB_USER u
WHERE
l.nreaderidn IN ( SELECT
regexp_substr(GETREADERSBYFUNC('LOCKER'), '[^,]+', 1, level) FROM dual
connect by regexp_substr(GETREADERSBYFUNC('LOCKER'), '[^,]+', 1, level) is not null)
AND NDATETIME >= ((TO_DATE ('2020-01-27' || ' 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM') ) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60
AND ndatetime <= ((TO_DATE ('2020-01-28' || ' 12:00:00 PM', 'YYYY-MM-DD HH:MI:SS PM') ) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60
AND l.nuserid = u.suserid
AND l.nreaderidn = r.nreaderidn
ORDER BY 2, 4
This will not give you an error:
SELECT *
from TB_READER l
where cast(l.nreaderidn as varchar2(1024)) in (select GETREADERSBYDESC('LOCKER') devices FROM dual)
Just use the cast of the nreaderidn column.
But also be aware that you will search a varchar like for example '2' in the string(not an series of characters but one string) '1','2','3' so this will not retun any results.
Here is also a small example where you can see the errir being produced without a cast and solved when the cast is added:
https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=776ecd951aff56500938ac064b34788c

ORACLE SQL - How to check whether a time falls within a particular range?

There is a column 'DateTime' that displays the Date and Time in 'YYYY/MM/DD HH24:MI:SS' format.
I need to display only the rows that has time in a particular range(2AM - 6AM) regardless of the particular date.
I have a code that only displays the time range(2AM - 6AM) for the particular day. I need to display the rows that falls in the past 7 days with the time range 2AM-6AM.
SELECT *
FROM <table_name >
WHERE DateTime BETWEEN TO_DATE (
TO_CHAR (TRUNC (SYSDATE), 'DD-MM-YYYY')
|| ' '
|| '02:00:00',
'DD-MM-YYYY HH24:MI:SS')
AND TO_DATE (
TO_CHAR (TRUNC (SYSDATE), 'DD-MM-YYYY')
|| ' '
|| '06:00:00',
'DD-MM-YYYY HH24:MI:SS')
ORDER BY 1 DESC
SELECT *
FROM your_table
WHERE TO_CHAR( DateTime, 'HH24MMSS' ) BETWEEN '020000' AND '060000'
AND DateTime >= TRUNC( SYSDATE ) - INTERVAL '7' DAY
AND DateTime < TRUNC( SYSDATE ) + INTERVAL '1' DAY
or
SELECT *
FROM your_table
WHERE DateTime BETWEEN TRUNC( DateTime ) + INTERVAL '2' HOUR
AND TRUNC( DateTime ) + INTERVAL '6' HOUR
AND DateTime >= TRUNC( SYSDATE ) - INTERVAL '7' DAY
AND DateTime < TRUNC( SYSDATE ) + INTERVAL '1' DAY
You need two conditions for that: one for the hour being between 02 and 05, and one for the day being in the last seven days:
SELECT *
FROM <table_name>
WHERE to_char(DateTime, 'HH') BETWEEN '02' and '05' AND
DateTime BETWEEN SYSDATE - 7 AND SYSDATE
ORDER BY 1 DESC
In this case, I think the easiest way is string comparison:
WHERE SUBSTR(DateTime, 12, 2) BETWEEN '02' and '05'
Note: Between is inclusive so this should get everything up to 05:59:59.
SELECT *
FROM <table_name >
WHERE DateTime BETWEEN TO_DATE (
TO_CHAR (TRUNC (SYSDATE)-7, 'DD-MM-YYYY')
|| ' '
|| '02:00:00',
'DD-MM-YYYY HH24:MI:SS')
AND TO_DATE (
TO_CHAR (TRUNC (SYSDATE), 'DD-MM-YYYY')
|| ' '
|| '06:00:00',
'DD-MM-YYYY HH24:MI:SS')
select * from table_name where to_char(datetime,'HH24')
between '2' and '6' and to_char(datetime,'dd-mon-yy')
between to_char(sysdate,'dd-mon-yy') and to_char(sysdate-7,'dd-mon-yy');

Query that display all dates in a range

I want to create a query that displays dates and counts. I want to display all dates within a range including dates with zero counts. I am looking for a way to do this WITHOUT using temp tables.
The output might look like:
Time Count
1/1/2017 01:00 AM 23
1/1/2017 02:00 AM 0
1/1/2017 03:00 AM 0
1/1/2017 04:00 AM 12
I was able to come up with an solutions that adds zero count rows. An example of the result set is below. You will see there are some duplicate DayOfWeekByHour values. I will need to figure out how to sum those up, but this is basically what I was looking for. See Example code link
DayOfWeekByHour, Count
100, 0
101, 0
102, 0
100, 23
201, 100
example of code
SELECT
TO_NUMBER(MOD(V,7)+1 || LPAD(MOD(V,24),2,'0')) as DayOfWeekByHour, 0
FROM (
SELECT 1 V FROM DUAL
) T
MODEL DIMENSION BY (ROWNUM R)
MEASURES (V)
RULES ITERATE (168) (
V[ITERATION_NUMBER] = CV(R) + 1
)
UNION
SELECT
TO_NUMBER(
TO_CHAR(
TO_DATE(
EXTRACT(MONTH FROM ve.CREATED_TIMESTAMP) || '/' ||
EXTRACT(DAY FROM ve.CREATED_TIMESTAMP) || '/' ||
EXTRACT(YEAR FROM ve.CREATED_TIMESTAMP) ,'MM/DD/YYYY'),'D'),'99') * 100 + TO_NUMBER(TO_CHAR(TO_DATE(
EXTRACT(MONTH FROM ve.CREATED_TIMESTAMP) || '/' ||
EXTRACT(DAY FROM ve.CREATED_TIMESTAMP) || '/' ||
EXTRACT(YEAR FROM ve.CREATED_TIMESTAMP) || ' ' ||
EXTRACT(HOUR FROM ve.CREATED_TIMESTAMP) || ':' ||
EXTRACT(MINUTE FROM ve.CREATED_TIMESTAMP)
,'MM/DD/YYYY HH24:MI'
)
,'HH24'
)
, '99') AS DayOfWeekByHour,
COUNT(*)
FROM
VIEWER.VIEWING_EVENT ve
WHERE
ve.CREATED_TIMESTAMP >= TO_TIMESTAMP('02-12-2016 00:00:00', 'dd-mm-yyyy hh24:mi:ss') AND
ve.CREATED_TIMESTAMP <= TO_TIMESTAMP('02-12-2017 00:00:00', 'dd-mm-yyyy hh24:mi:ss')
GROUP BY
TO_NUMBER(
TO_CHAR(
TO_DATE(
EXTRACT(MONTH FROM ve.CREATED_TIMESTAMP) || '/' ||
EXTRACT(DAY FROM ve.CREATED_TIMESTAMP) || '/' ||
EXTRACT(YEAR FROM ve.CREATED_TIMESTAMP) ,'MM/DD/YYYY'),'D'),'99') * 100 + TO_NUMBER(TO_CHAR(TO_DATE(
EXTRACT(MONTH FROM ve.CREATED_TIMESTAMP) || '/' ||
EXTRACT(DAY FROM ve.CREATED_TIMESTAMP) || '/' ||
EXTRACT(YEAR FROM ve.CREATED_TIMESTAMP) || ' ' ||
EXTRACT(HOUR FROM ve.CREATED_TIMESTAMP) || ':' ||
EXTRACT(MINUTE FROM ve.CREATED_TIMESTAMP)
,'MM/DD/YYYY HH24:MI'
)
,'HH24'
)
, '99')
ORDER BY
DayOfWeekByHour
;

Get data in range using oracle

Please help me to solve this.
I have a table that contain users check in (checktype = I) and check out (checktype = 0) time everyday, and I would like to get the total amount of check in time per user which occur > 08:00 AM in a specific date range.
I am using the query below, but only handle one day per query not in a range, so I have to loop using javascript to get the amount of delay ( > 08:00 AM) per user for example from 01/06/2012 to 06/06/2012
Please help me to get the amount (count) check in time > 08:00 AM per user (ex: userid 708) from ex:01/06/2012 to 06/06/2012 in a single query.
with tt as
(
select TO_DATE('01/06/2012 08:00:00','dd/mm/yyyy hh24:mi:ss') date1 ,
checktime date2
from
checkinout
where
userid = '708' and
to_char(checktime,'dd/mm/yyyy') = '01/06/2012' and
checktype='I' -- checktype I is check in
) , t2 as
(
select numtodsinterval(date2 - date1,'day') dsinterval from tt
)
select extract(hour from dsinterval) || ' hours ' ||
extract(minute from dsinterval) || ' minutes ' ||
round(extract(second from dsinterval)) || ' seconds' late from t2
I assume you wanted to get how many hours late (i.e. after 08:00) the checkins have been done:
with t2 as (
select userid
,numtodsinterval(sum(checktime - (trunc(checktime)+8/24)),'day') dsinterval
,count(1) cnt
from checkinout
where userid='708'
and checktime > trunc(checktime)+8/24
and trunc(checktime) between to_date('01/06/2012','DD/MM/YYYY') and to_date('06/06/2012','DD/MM/YYYY')
and checktype = 'I'
group by userid
)
select extract(hour from dsinterval) || ' hours ' ||
extract(minute from dsinterval) || ' minutes ' ||
round(extract(second from dsinterval)) || ' seconds' late
,cnt
from t2;
See http://sqlfiddle.com/#!4/c4670/11 for my test case.
edit: added column "cnt" to show how many times
Consider the following example on base of this you can write your own logic
WITH tbl AS
(SELECT SYSDATE dt
FROM DUAL
UNION
SELECT SYSDATE + (1 + (10 / 1440))
FROM DUAL
UNION
SELECT SYSDATE + (2 + (12 / 1440))
FROM DUAL
UNION
SELECT SYSDATE + (3 + (13 / 1440))
FROM DUAL
UNION
SELECT SYSDATE + (6 + (15 / 1440))
FROM DUAL
UNION
SELECT SYSDATE + (8 + (18 / 1440))
FROM DUAL)
SELECT EXTRACT (HOUR FROM dsinterval)
|| ' hours '
|| EXTRACT (MINUTE FROM dsinterval)
|| ' minutes '
|| ROUND (EXTRACT (SECOND FROM dsinterval))
|| ' seconds' late
FROM (SELECT NUMTODSINTERVAL (dt1 - dt2, 'day') dsinterval
FROM (SELECT TO_DATE (TO_CHAR (dt, 'DD/MM/YYYY') || ' 08:00:00',
'DD/MM/YYYY HH24:MI:SS'
) dt1,
TO_DATE (TO_CHAR (dt, 'DD/MM/YYYY HH24:MI:SS'),
'DD/MM/YYYY HH24:MI:SS'
) dt2
FROM tbl
WHERE dt BETWEEN SYSDATE + 2 AND SYSDATE + 5))
As per code you can write like
SELECT EXTRACT (HOUR FROM dsinterval)
|| ' hours '
|| EXTRACT (MINUTE FROM dsinterval)
|| ' minutes '
|| ROUND (EXTRACT (SECOND FROM dsinterval))
|| ' seconds' late
FROM (SELECT NUMTODSINTERVAL (dt1 - dt2, 'day') dsinterval
FROM (SELECT TO_DATE (TO_CHAR (checktime , 'DD/MM/YYYY') || ' 08:00:00',
'DD/MM/YYYY HH24:MI:SS'
) dt1,
TO_DATE (checktime, 'DD/MM/YYYY HH24:MI:SS') dt2
FROM checkinout
WHERE checktime BETWEEN start_date AND end_date
AND checktype='I'))