select product_name,start_tm,end_tm,load_date,bus_dt from A.product
Output :
Product_name start_tm end_tm Load_date bus_dt
Pencil 01-jul-21 12:00 am 01-jul-21 12:30 am 03-jul-21 01-jul-21
Pencil 01-jul-21 04:00 am 01-jul-21 04:30 am 03-jul-21 01-jul-21
Eraser 01-jul-21 01:00 am 01-jul-21 01:30 am 01-jul-21 02-jul-21
Eraser 01-jul-21 04:00 am 01-jul-21 04:30 am 02-jul-21 02-jul-21
If Product is Eraser then output should be latest load_date
Product_name start_tm end_tm Load_date bus_dt
Eraser 01-jul-21 04:00 am 01-jul-21 04:30 am 02-jul-21 02-jul-21
If Product is Eraser then output should be latest load_date since load_date as same
for product Pencil then it should look for Max end_tm
Product_name start_tm end_tm Load_date bus_dt
Pencil 01-jul-21 04:00 am 01-jul-21 04:30 am 03-jul-21 01-jul-21
how to achieve it using Rank?
You said it all, I believe. Sample data in lines #1 - 14; query begins at line #15.
SQL> with product (product_name, start_tm, end_tm, load_date, bus_dt) as
2 (select 'pencil', to_date('01.07.2021 00:00', 'dd.mm.yyyy hh24:mi'),
3 to_date('01.07.2021 00:30', 'dd.mm.yyyy hh24:mi'),
4 date '2021-07-03', date '2021-07-01' from dual union all
5 select 'pencil', to_date('01.07.2021 04:00', 'dd.mm.yyyy hh24:mi'),
6 to_date('01.07.2021 04:30', 'dd.mm.yyyy hh24:mi'),
7 date '2021-07-03', date '2021-07-01' from dual union all
8 select 'eraser', to_date('01.07.2021 01:00', 'dd.mm.yyyy hh24:mi'),
9 to_date('01.07.2021 01:30', 'dd.mm.yyyy hh24:mi'),
10 date '2021-07-01', date '2021-07-01' from dual union all
11 select 'eraser', to_date('01.07.2021 04:00', 'dd.mm.yyyy hh24:mi'),
12 to_date('01.07.2021 04:30', 'dd.mm.yyyy hh24:mi'),
13 date '2021-07-02', date '2021-07-02' from dual
14 ),
15 temp as
16 (select p.*,
17 rank() over (partition by product_name
18 order by load_date desc, end_tm desc) rnk
19 from product p
20 )
21 select *
22 from temp
23 where rnk = 1;
PRODUC START_TM END_TM LOAD_DATE BUS_DT RNK
------ ---------------- ---------------- ---------------- ---------------- ----------
eraser 01.07.2021 04:00 01.07.2021 04:30 02.07.2021 00:00 02.07.2021 00:00 1
pencil 01.07.2021 04:00 01.07.2021 04:30 03.07.2021 00:00 01.07.2021 00:00 1
SQL>
Related
I have a table with normal DATE field in it:
5/9/2022 2:32:02 AM
5/9/2022 12:33:02 PM
5/9/2022 10:34:02 AM
5/9/2022 10:20:02 AM
5/9/2022 6:54:02 AM
5/9/2022 4:28:02 AM
5/9/2022 5:08:02 AM
I need a query that I can run that will give me the record that is the closest to the top of the hour I am asking for. So like, which is closest to 5:00am, or 7:00am, or 12:00pm.
Thanks!
A query like the one below can be used to show each record that is closest to the "top of the hour". In your sample data, none of the records overlap to the nearest "top of the hour", so all the records will be shown. If you add additional dates that are closer together to the top of the hour, then only the the dates closest to the "top of the hour" will be shown.
Query
WITH
sample_dates (dt)
AS
(SELECT TO_DATE ('5/9/2022 2:32:02 AM', 'MM/DD/YYYY HH:MI:SS PM') FROM DUAL
UNION ALL
SELECT TO_DATE ('5/9/2022 12:33:02 PM', 'MM/DD/YYYY HH:MI:SS PM') FROM DUAL
UNION ALL
SELECT TO_DATE ('5/9/2022 10:34:02 AM', 'MM/DD/YYYY HH:MI:SS PM') FROM DUAL
UNION ALL
SELECT TO_DATE ('5/9/2022 10:20:02 AM', 'MM/DD/YYYY HH:MI:SS PM') FROM DUAL
UNION ALL
SELECT TO_DATE ('5/9/2022 6:54:02 AM', 'MM/DD/YYYY HH:MI:SS PM') FROM DUAL
UNION ALL
SELECT TO_DATE ('5/9/2022 4:28:02 AM', 'MM/DD/YYYY HH:MI:SS PM') FROM DUAL
UNION ALL
SELECT TO_DATE ('5/9/2022 5:08:02 AM', 'MM/DD/YYYY HH:MI:SS PM') FROM DUAL)
SELECT TO_CHAR (dt, 'MM/DD/YYYY HH:MI:SS PM') AS dt,
TO_CHAR (nearest_hour, 'MM/DD/YYYY HH:MI:SS PM') AS nearest_hour
FROM (SELECT dt,
nearest_hour,
ROW_NUMBER () OVER (PARTITION BY nearest_hour ORDER BY time_from_hour) AS time_rank
FROM (SELECT dt,
CASE
WHEN dt - TRUNC (dt, 'HH') <
ABS ((TRUNC (dt, 'HH') + INTERVAL '1' HOUR) - dt)
THEN
TRUNC (dt, 'HH')
ELSE
TRUNC (dt, 'HH') + INTERVAL '1' HOUR
END AS nearest_hour,
LEAST (dt - TRUNC (dt, 'HH'),
ABS ((TRUNC (dt, 'HH') + INTERVAL '1' HOUR) - dt)) AS time_from_hour
FROM sample_dates))
WHERE time_rank = 1
ORDER BY 1;
Result
DT NEAREST_HOUR
_________________________ _________________________
05/09/2022 02:32:02 AM 05/09/2022 03:00:00 AM
05/09/2022 04:28:02 AM 05/09/2022 04:00:00 AM
05/09/2022 05:08:02 AM 05/09/2022 05:00:00 AM
05/09/2022 06:54:02 AM 05/09/2022 07:00:00 AM
05/09/2022 10:20:02 AM 05/09/2022 10:00:00 AM
05/09/2022 10:34:02 AM 05/09/2022 11:00:00 AM
05/09/2022 12:33:02 PM 05/09/2022 01:00:00 PM
To get the closest row to a particular hour on any day then, from Oracle 12, you can use:
SELECT *
FROM table_name
ORDER BY ABS(
TRUNC(yourDate) + INTERVAL '07:00:00' HOUR TO SECOND
- yourDate
)
FETCH FIRST ROW ONLY;
Which, for the sample data:
CREATE TABLE table_name (id, yourDate) AS
SELECT 1, DATE '2022-05-09' + INTERVAL '02:32:02' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 2, DATE '2022-05-09' + INTERVAL '12:33:02' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 3, DATE '2022-05-09' + INTERVAL '10:34:02' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 4, DATE '2022-05-09' + INTERVAL '10:20:02' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 5, DATE '2022-05-09' + INTERVAL '06:54:02' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 6, DATE '2022-05-09' + INTERVAL '04:28:02' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 7, DATE '2022-05-09' + INTERVAL '05:08:02' HOUR TO SECOND FROM DUAL;
Outputs:
ID
YOURDATE
5
2022-05-09 06:54:02
If you want the closest hour to each of your rows then:
SELECT t.*,
TRUNC(yourDate, 'HH') + ROUND((yourDate - TRUNC(yourDate, 'HH'))*24)/24
AS nearest_hour
FROM table_name t
Outputs:
ID
YOURDATE
NEAREST_HOUR
1
2022-05-09 02:32:02
2022-05-09 03:00:00
2
2022-05-09 12:33:02
2022-05-09 13:00:00
3
2022-05-09 10:34:02
2022-05-09 11:00:00
4
2022-05-09 10:20:02
2022-05-09 10:00:00
5
2022-05-09 06:54:02
2022-05-09 07:00:00
6
2022-05-09 04:28:02
2022-05-09 04:00:00
7
2022-05-09 05:08:02
2022-05-09 05:00:00
If, for each closest hour, you want the single closest row then:
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY nearest_hour ORDER BY ABS(nearest_hour - yourDate))
AS rn
FROM (
SELECT t.*,
TRUNC(yourDate, 'HH') + ROUND((yourDate - TRUNC(yourDate, 'HH'))*24)/24
AS nearest_hour
FROM table_name t
) t
)
WHERE rn = 1
Outputs:
ID
YOURDATE
NEAREST_HOUR
RN
1
2022-05-09 02:32:02
2022-05-09 03:00:00
1
6
2022-05-09 04:28:02
2022-05-09 04:00:00
1
7
2022-05-09 05:08:02
2022-05-09 05:00:00
1
5
2022-05-09 06:54:02
2022-05-09 07:00:00
1
4
2022-05-09 10:20:02
2022-05-09 10:00:00
1
3
2022-05-09 10:34:02
2022-05-09 11:00:00
1
2
2022-05-09 12:33:02
2022-05-09 13:00:00
1
db<>fiddle here
I have one requirement where I have to show the records between specific date and time every day in one week duration.
in one week duration( 2019-04-01 till 2019-04-06) ,for instance record of 2019-04-01 at 19 PM till 8 Am of 2019-04-02 ,and record of 2019-04-02 at 19 PM till 08 AM of 2019-04-03 and ...
would you please help me!
Use recursive query to create proper periods then join with your data or do it simpler with condition like here:
select callbegin, callerno
from table4
where callerno in ('7032','750')
and callbegin between timestamp '2019-04-01 19:00:00'
and timestamp '2019-04-06 08:00:00'
and ('19' <= to_char(callbegin, 'hh24') or to_char(callbegin, 'hh24') < '08');
demo
Here's how I understood the question.
SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi';
Session altered.
SQL> break on period;
SQL> with
2 data (id, datum) as
3 (select 1, to_date('01.04.2019 15:30', 'dd.mm.yyyy hh24:mi') from dual union all
4 select 2, to_date('01.04.2019 20:00', 'dd.mm.yyyy hh24:mi') from dual union all -- 1st
5 select 3, to_date('02.04.2019 01:15', 'dd.mm.yyyy hh24:mi') from dual union all -- 1st perios
6 select 4, to_date('02.04.2019 11:00', 'dd.mm.yyyy hh24:mi') from dual union all
7 select 5, to_date('02.04.2019 23:15', 'dd.mm.yyyy hh24:mi') from dual union all -- 2nd period
8 select 6, to_date('03.04.2019 00:10', 'dd.mm.yyyy hh24:mi') from dual union all -- 2nd
9 select 7, to_date('04.04.2019 22:20', 'dd.mm.yyyy hh24:mi') from dual -- 3rd period
10 ),
11 test as
12 (select date '2019-04-01' dstart,
13 date '2019-04-06' dend
14 from dual
15 ),
16 inter as
17 (select dstart + level - 1 datum
18 from test
19 connect by level <= dend - dstart + 1
20 ),
21 from_to as
22 (select datum + 19/24 date_from,
23 lead(datum) over (order by datum) + 8/24 date_to
24 from inter
25 )
26 select f.date_From ||' - '|| f.date_to period,
27 d.id,
28 d.datum
29 from data d join from_to f on 1 = 1
30 where d.datum between f.date_from and f.date_to
31 order by f.date_From, d.id;
PERIOD ID DATUM
----------------------------------- ---------- ----------------
01.04.2019 19:00 - 02.04.2019 08:00 2 01.04.2019 20:00
3 02.04.2019 01:15
02.04.2019 19:00 - 03.04.2019 08:00 5 02.04.2019 23:15
6 03.04.2019 00:10
04.04.2019 19:00 - 05.04.2019 08:00 7 04.04.2019 22:20
SQL>
This is how to filter data by days and time by one week:
With date_list as (
Select
to_date(to_char( (sysdate - level), 'yyyymmdd') || '19', 'yyyymmddhh24') begin_time,
to_date(to_char( ((sysdate - level)+1), 'yyyymmdd') || '08', 'yyyymmddhh24') end_time
From dual connect by level <= 7
)
Select begin_time, your_table.*
From
your_table t1,
date_list t2
Where
t1.your_date between t2.begin_time and t2.end_time;
I have two tables AVAIL and AVAIL_TIMES. AVAIL contains avail_id, avail_date, open_flag. AVAIL_TIMES contains avail_times_id, Avail_id, Start_Time, End_time. All date and time fields are typed as DATE
If a date is flagged in the avail open_flag column it means that the facility is open for that date, but the times it is open is listed in avail_times. There can be multiple time ranges for a particular day.
I need to return a list of times it is not open for that day.
For Example (one day of many)
Open times for day:
Start_time: 08:00 End_time 10:00
Start_time: 12:00 End_time 14:00
Start_time: 15:00 End_time 17:00
I want it to return something like:
00:00 - 07:59
10:01 - 11:59
14:01 - 14:59
17:01 - 23:59
I think I would be able to work through this with a temporary table and some plsql logic, but ideally this would be a pure sql solution.
I am not exactly sure how you want to input the date of interest (I used a bind variable, passed in as a string - but that may not be the right way for you, perhaps you want to join to your other table, etc.) - or the exact output you want. In any case, the query below demonstrates the "core" of the code you need to achieve this kind of output from the inputs.
alter session set nls_date_format='mm/dd/yyyy hh24:mi';
with
avail_times ( start_time, end_time ) as (
select to_date('06/20/2017 08:00'), to_date('06/20/2017 10:00') from dual union all
select to_date('06/20/2017 12:00'), to_date('06/20/2017 14:00') from dual union all
select to_date('06/20/2017 15:00'), to_date('06/20/2017 17:00') from dual
)
select trunc(min(start_time)) as start_time, min(start_time) as end_time
from avail_times
where trunc(start_time) = to_date(:input_date, 'mm/dd/yyyy')
union all
select end_time,
lead(start_time, 1, trunc(start_time) + 1) over (order by start_time)
from avail_times
where trunc(end_time) = trunc(start_time)
order by start_time
;
START_TIME END_TIME
---------------- ----------------
06/20/2017 00:00 06/20/2017 08:00
06/20/2017 10:00 06/20/2017 12:00
06/20/2017 14:00 06/20/2017 15:00
06/20/2017 17:00 06/21/2017 00:00
Another Approach. Hope this helps.
SELECT ID,
START_TME,
END_TM,
DIFF_TM
FROM
--Not part of SQL just to simulate the table data
(WITH TMP AS
(SELECT 1 ID,
TO_DATE('06/27/2017 00:00','mm/dd/yyyy hh24:mi') START_TME,
TO_DATE('06/27/2017 08:00','mm/dd/yyyy hh24:mi') END_TM
FROM DUAL
UNION ALL
SELECT 1 ID,
TO_DATE('06/27/2017 10:00','mm/dd/yyyy hh24:mi') START_TME,
TO_DATE('06/27/2017 15:00','mm/dd/yyyy hh24:mi') END_TM
FROM DUAL
UNION ALL
SELECT 1 ID,
TO_DATE('06/27/2017 16:00','mm/dd/yyyy hh24:mi') START_TME,
TO_DATE('06/27/2017 17:00','mm/dd/yyyy hh24:mi') END_TM
FROM DUAL
UNION ALL
SELECT 1 id,
to_date('06/27/2017 17:00','mm/dd/yyyy hh24:mi') start_tme,
TO_DATE('06/27/2017 18:00','mm/dd/yyyy hh24:mi') END_TM
FROM DUAL
)
--SQL start from here
SELECT TMP.*,
LEAD(START_TME) OVER(PARTITION BY ID ORDER BY 1 DESC) next_st_tm,
LEAD(END_TM) OVER(PARTITION BY ID ORDER BY 1 DESC) NEXT_EN_TM,
EXTRACT( HOUR FROM TO_TIMESTAMP(LEAD(START_TME) OVER(PARTITION BY ID ORDER BY 1 DESC),'MM/DD/YYYY HH24:MI'))- EXTRACT(HOUR FROM TO_TIMESTAMP(end_tm,'MM/DD/YYYY HH24:MI')) DIFF_TM
FROM TMP
ORDER BY 1 ,
2
)
WHERE DIFF_TM <> 0;
In an Oracle table I have data coming in on 15 minute intervals across many different unique IDs. For example, the data might look something like this:
ObjectID Date
123 1/1/2016 00:00:00
123 1/1/2016 00:15:00
123 1/1/2016 00:30:00
123 1/1/2016 00:45:00
123 1/1/2016 01:00:00
456 1/1/2016 00:00:00
456 1/1/2016 00:15:00
456 1/1/2016 00:30:00
456 1/1/2016 00:45:00
456 1/1/2016 01:00:00
789 1/1/2016 00:00:00
789 1/1/2016 00:15:00
789 1/1/2016 00:30:00
789 1/1/2016 00:45:00
789 1/1/2016 01:00:00
This is a very simple example. In reality, the objectIDs are not sorted in a uniform order and there's a possibility of missing intervals. Thus the data really looks more like this:
ObjectID Date
456 1/1/2016 00:15:00
456 1/1/2016 00:30:00
123 1/1/2016 00:30:00
123 1/1/2016 00:45:00
123 1/1/2016 01:00:00
456 1/1/2016 00:45:00
456 1/1/2016 01:00:00
789 1/1/2016 00:45:00
789 1/1/2016 01:00:00
789 1/1/2016 00:00:00
789 1/1/2016 00:15:00
789 1/1/2016 00:30:00
I would like to be able to get a count of the missing intervals across all of the objectIDs for a specific date range. In the above, there are three missing intervals:
123 1/1/2016 00:00:00
123 1/1/2016 00:15:00
456 1/1/2016 00:00:00
I'm looking for a query that would catch these and return a count of 3 if given a date range of 1/1/2016 00:00:00 - 1/1/2016 1:00:00.
I think something like this may work. May be more efficient method.
select count(*) from your_table
where your_table.date not in
(
SELECT dateval
FROM
( WITH dates AS
(SELECT to_date('01/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') dstart,
to_date('01/01/2016 01:00:00','MM/DD/YYYY HH24:MI:SS') dend
FROM dual
)
SELECT dstart + rownum/96.0 dateval
FROM dates
CONNECT BY rownum <=
(SELECT (dend - dstart)*96 FROM dates
)
)
)
The "connect by" counts the number of 15 minute intervals between the start/end date, then generates each of the date/times in 15 minute increments starting with the start date/time.
If you only need counting, an approach could be count the expected intervals and make the difference with the number of intervals really found:
with test(ObjectID, Date_) as
(
select 456, to_date('1/1/2016 00:15:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 456, to_date('1/1/2016 00:30:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 123, to_date('1/1/2016 00:30:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 123, to_date('1/1/2016 00:45:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 123, to_date('1/1/2016 01:00:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 456, to_date('1/1/2016 00:45:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 456, to_date('1/1/2016 01:00:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 789, to_date('1/1/2016 00:45:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 789, to_date('1/1/2016 01:00:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 789, to_date('1/1/2016 00:00:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 789, to_date('1/1/2016 00:15:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 789, to_date('1/1/2016 00:30:00', 'dd/mm/yyyy hh24:mi:ss') from dual
),
input_dates(start_date, end_date) as
( select to_date('1/1/2016 00:00:00', 'dd/mm/yyyy hh24:mi:ss'),
to_date('1/1/2016 01:00:00', 'dd/mm/yyyy hh24:mi:ss') from dual)
--
select (count( distinct objectId) * (input_dates.end_date - input_dates.start_date) * 24 * 5)
-
sum(
case when date_ between input_dates.start_date and input_dates.end_date
then 1
else 0
end
) as missing
from test, input_dates
In case of an objectID that is in your table, but does not have any interval in the input period, this will return 5, to say that it's missing all the intervals.
If you want to check only missing intervals on IDs having at least one interval in the period, you can simply remove the BETWEEN condition from the SUM and add in as WHERE clause
Let me take a shot at it.... (Aleksej i took off from your answer).
with
--
-- Test case supplied
--
test(ObjectID, Date_) as
(
select 456, to_date('1/1/2016 00:15:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 456, to_date('1/1/2016 00:30:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 123, to_date('1/1/2016 00:30:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 123, to_date('1/1/2016 00:45:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 123, to_date('1/1/2016 01:00:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 456, to_date('1/1/2016 00:45:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 456, to_date('1/1/2016 01:00:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 789, to_date('1/1/2016 00:45:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 789, to_date('1/1/2016 01:00:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 789, to_date('1/1/2016 00:00:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 789, to_date('1/1/2016 00:15:00', 'dd/mm/yyyy hh24:mi:ss') from dual union all
select 789, to_date('1/1/2016 00:30:00', 'dd/mm/yyyy hh24:mi:ss') from dual
),
--
-- Intervals generates all possible 15 minutes intervals within the given parameters
--
intervals (Date_) as
(
select to_date('1/1/2016 00:00:00', 'dd/mm/yyyy hh24:mi:ss') + ((15/1440) * (level - 1))
from dual
connect by level <= 24 * (to_date('1/1/2016 01:00:00', 'dd/mm/yyyy hh24:mi:ss') - to_date('1/1/2016 00:00:00', 'dd/mm/yyyy hh24:mi:ss')) * 4
)
--
-- Simple minus to find the missing intervals
--
select distinct test.ObjectID, to_char(intervals.Date_ ,'YYYY/MM/DD HH24:MI:SS') dt
from test,
intervals
minus
select test.ObjectID, to_char(test.Date_,'YYYY/MM/DD HH24:MI:SS') dt
from test
/
When I execute the missing intervals:
OBJECTID DT
---------- -------------------
123 2016/01/01 00:00:00
123 2016/01/01 00:15:00
456 2016/01/01 00:00:00
I have a requirement to show 1 to 20 questions how many teams answered for 0-23 hours. The table structure
Team_id Question_id Updated
124 25092 02-SEP-14 11:30:12 AM
15 25076 02-SEP-14 02:31:15 PM
258 25061 02-SEP-14 03:02:33 PM
298 25196 02-SEP-14 03:32:49 PM
450 25203 02-SEP-14 07:01:05 PM
471 25351 02-SEP-14 07:47:31 PM
482 25350 02-SEP-14 08:01:03 PM
78 24924 02-SEP-14 08:01:29 PM
541 26032 02-SEP-14 09:35:00 PM
708 26485 02-SEP-14 12:19:48 PM
726 26125 02-SEP-14 01:00:11 PM
145 26221 02-SEP-14 03:45:32 PM
824 26436 02-SEP-14 06:30:16 PM
87 26505 02-SEP-14 06:30:22 PM
825 26488 02-SEP-14 06:31:34 PM
466 26488 02-SEP-14 06:34:48 PM
868 26091 02-SEP-14 08:30:59 PM
1356 28852 02-SEP-14 07:45:14 PM
1342 28852 02-SEP-14 07:45:27 PM
Query should return
Hours 1 2 3 4 5 to 20
10 6 0 2 3 6 to 25
11 3 2 1 1 7 to 300
12 2 0 5 0 7 to 30
13 1 6 1 1 7 to 40
these are count of team that answered only 1 question in hour 10
these are count of team that answered only 2 question in hour 10 etc.
Note it is not 1st or 2nd question.
Thanks
Arun
You need something like this I suppose:
select hour,
count(decode(cnt, 1, 1)) as q1,
count(decode(cnt, 2, 1)) as q2,
count(decode(cnt, 3, 1)) as q3,
count(decode(cnt, 4, 1)) as q4,
...
count(decode(cnt, 20, 1)) as q20
from (
select to_char(updated, 'HH24') as hour
, count(*) as cnt
from &table_name
group by to_char(updated, 'HH24'), team_id
)
group by hour;
As far as I understand, perhaps you want something like this :
SQL> WITH DATA AS(
2 SELECT 124 team_id, 25092 question_id, to_date('02-SEP-14 11:30:12 AM','DD-MON-RR HH:MI:SS AM') UPDATED FROM DUAL UNION ALL
3 SELECT 15 , 25076 ,to_date('02-SEP-14 02:31:15 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
4 SELECT 258 , 25061 ,to_date('02-SEP-14 03:02:33 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
5 SELECT 298 , 25196 ,to_date('02-SEP-14 03:32:49 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
6 SELECT 450 , 25203 ,to_date('02-SEP-14 07:01:05 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
7 SELECT 471 , 25351 ,to_date('02-SEP-14 07:47:31 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
8 SELECT 482 , 25350 ,to_date('02-SEP-14 08:01:03 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
9 SELECT 78 , 24924 ,to_date('02-SEP-14 08:01:29 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
10 SELECT 541 , 26032 ,to_date('02-SEP-14 09:35:00 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
11 SELECT 708 , 26485 ,to_date('02-SEP-14 12:19:48 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
12 SELECT 726 , 26125 ,to_date('02-SEP-14 01:00:11 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
13 SELECT 145 , 26221 ,to_date('02-SEP-14 03:45:32 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
14 SELECT 824 , 26436 ,to_date('02-SEP-14 06:30:16 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
15 SELECT 87 , 26505 ,to_date('02-SEP-14 06:30:22 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
16 SELECT 825 , 26488 ,to_date('02-SEP-14 06:31:34 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
17 SELECT 466 , 26488 ,to_date('02-SEP-14 06:34:48 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
18 SELECT 868 , 26091 ,to_date('02-SEP-14 08:30:59 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
19 SELECT 1356 , 28852 ,to_date('02-SEP-14 07:45:14 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL UNION ALL
20 SELECT 1342 , 28852 ,to_date('02-SEP-14 07:45:27 PM','DD-MON-RR HH:MI:SS AM') FROM DUAL)
21 SELECT 5 hours,
22 COUNT(team_id)
23 FROM DATA
24 WHERE UPDATED BETWEEN to_date('02-SEP-14 10:00:01','DD-MON-RR HH24:MI:SS') AND to_date('02-SEP-14 14:59:59','DD-MON-RR HH24:MI:SS')
25 UNION
26 SELECT 6 hours,
27 COUNT(team_id)
28 FROM DATA
29 WHERE UPDATED BETWEEN to_date('02-SEP-14 10:00:01','DD-MON-RR HH24:MI:SS') AND to_date('02-SEP-14 15:59:59','DD-MON-RR HH24:MI:SS')
30 UNION
31 SELECT 10 hours,
32 COUNT(team_id)
33 FROM DATA
34 WHERE UPDATED BETWEEN to_date('02-SEP-14 10:00:01','DD-MON-RR HH24:MI:SS') AND to_date('02-SEP-14 19:59:59','DD-MON-RR HH24:MI:SS')
35 UNION
36 SELECT 24 hours,
37 COUNT(team_id)
38 FROM DATA
39 WHERE UPDATED BETWEEN to_date('02-SEP-14 00:00:01','DD-MON-RR HH24:MI:SS') AND to_date('02-SEP-14 23:59:59','DD-MON-RR HH24:MI:SS')
40 /
HOURS COUNT(TEAM_ID)
---------- --------------
5 4
6 7
10 15
24 19
The time interval as an example, I took varying intervals, and the HOURS column is the time interval mentioned in the WHERE clause.