Related
enter image description hereI have a dates column that I am trying to group in to specific groups. Some dates have passed other dates are in the future. I want to have group them by 1-30, 31- 59, 60 - 89, +90, so there would be 8 groups total for both those that have passed and those that are on the horizon. Below is what I have wrote so far, but I feel like I am over complicating and the more tweaks I make the more incorrect it becomes. Any insight is appreciated!
CASE WHEN DATEDIFF(CURRENT_DATE(),`date`) >= 90 THEN '90 days past'
WHEN DATEDIFF(CURRENT_DATE(),`date`) >= 60 THEN '60 days past'
WHEN DATEDIFF(CURRENT_DATE(),`date`) >= 30 THEN '30 days past'
WHEN DATEDIFF(`date`,CURRENT_DATE()) >= 90 THEN '90 days future'
WHEN DATEDIFF(`date`,CURRENT_DATE()) >= 60 THEN '60 days future'
WHEN DATEDIFF(`date`,CURRENT_DATE()) >= 30 THEN 'Next 30 days'
ELSE 'Not Late'
END
I think it's okay.
I would just use the same datediff for each.
create table test (`date` date);
insert into test values
( date_add(current_date, interval -90 day) ),
( date_add(current_date, interval -89 day) ),
( date_add(current_date, interval -60 day) ),
( date_add(current_date, interval -59 day) ),
( date_add(current_date, interval -30 day) ),
( date_add(current_date, interval -29 day) ),
( date_add(current_date, interval 29 day) ),
( date_add(current_date, interval 30 day) ),
( date_add(current_date, interval 59 day) ),
( date_add(current_date, interval 60 day) ),
( date_add(current_date, interval 89 day) ),
( date_add(current_date, interval 90 day) )
select `date`,
CASE
WHEN DATEDIFF(`date`, CURRENT_DATE) <= -90 THEN '90 days past'
WHEN DATEDIFF(`date`, CURRENT_DATE) <= -60 THEN '60 days past'
WHEN DATEDIFF(`date`, CURRENT_DATE) <= -30 THEN '30 days past'
WHEN DATEDIFF(`date`, CURRENT_DATE) >= 90 THEN '90 days future'
WHEN DATEDIFF(`date`, CURRENT_DATE) >= 60 THEN '60 days future'
WHEN DATEDIFF(`date`, CURRENT_DATE) >= 30 THEN 'Next 30 days'
ELSE 'Not Late'
END as status
from test
date | status
:--------- | :-------------
2021-10-12 | 90 days past
2021-10-13 | 60 days past
2021-11-11 | 60 days past
2021-11-12 | 30 days past
2021-12-11 | 30 days past
2021-12-12 | Not Late
2022-02-08 | Not Late
2022-02-09 | Next 30 days
2022-03-10 | Next 30 days
2022-03-11 | 60 days future
2022-04-09 | 60 days future
2022-04-10 | 90 days future
db<>fiddle here
The values you see below are loaded with a query and they are related to a time stamp. What they ask me to insert is a rounded value; up and down. Rounding must be done at minutes of 15 and 30.
If the round is set to 15 and the marking has been made at 7:59, it is rounded off to 8:00 if the marking is at 8:01 am rounded to 8:15 am, as do I implement this thing within this query?
Query:
select Data, string_agg(Ore, ' ') as Ore
from (
select FORMAT(DataCreazione, 'dd/MM/yyyy', 'it-IT') as Data,
CONCAT(DATEPART(HOUR,DataCreazione), ':', DATEPART(MINUTE, DataCreazione)) as
Ore
from Marcatura
where IdUtente = 2
and (Stato='Ingresso' or Stato='Uscita')
and cast(DataCreazione as DateTime)
between cast(CONVERT(VARCHAR(10), CONVERT(date, '10-11-18', 5), 23) as datetime)
and cast(CONVERT(VARCHAR(10), CONVERT(date, '10-11-19', 5), 23) as datetime)
) t
group by Data
order by CONVERT(datetime, Data, 105) desc
Values:
05/07/2019 -- 14:45 19:27
04/07/2019 -- 11:41 11:41
07/06/2019 -- 12:39
01/06/2019 -- 8:27 8:27 8:27 8:27
18/04/2019 -- 15:41 15:41
08/04/2019 -- 11:52 11:54
01/04/2019 -- 7:25
27/03/2019 -- 21:38 21:38
23/03/2019 -- 13:32 13:32
08/03/2019 -- 21:20 21:20
04/03/2019 -- 21:48 21:48
02/03/2019 -- 8:3 8:3
If the state is equal to < Ingresso > it is rounded up to the top if the status is < Uscita > is rounded down, for example 07:59 becomes 08:00 whereas if it is 17:44 it becomes 17:45
I would use timefromparts():
select dateadd(minute,
(case when datepart(minute, #time) not in (0, 15, 30, 45) then 15 else 0 end),
timefromparts(datepart(hour, #time),
15 * floor(datepart(minute, #time) / 15.0) % 60,
0, 0, 0
)
)
This is a little more complicated because you want to round up. So the idea is to round down and then selectively add 15 minutes.
The Logic is much more simple than described, perhaps.
Try this approach:
EDIT: Applied logic to your own query
select Data, string_agg(Ore, ' ') as Ore
from (
select FORMAT(DataCreazione, 'dd/MM/yyyy', 'it-IT') as Data,
CONCAT(
(Case
when Datepart(MINUTE, DataCreazione) > 45
then Datepart(hour, Datacreazione)+1
else Datepart(hour, Datacreazione)
end)
,':'
,(case
when DATEPART(MINUTE, DataCreazione) between 0 and 15 then '15'
when DATEPART(MINUTE, DataCreazione) between 16 and 30 then '30'
when DATEPART(MINUTE, DataCreazione) between 31 and 45 then '45'
else '00' end
)) as Ore
from Marcatura
where IdUtente = 2
and (Stato='Ingresso' or Stato='Uscita')
and DataCreazione
between cast(CONVERT(VARCHAR(10), CONVERT(date, '10-11-18', 5), 23) as datetime)
and cast(CONVERT(VARCHAR(10), CONVERT(date, '10-11-19', 5), 23) as datetime)
) t
group by Data
order by CONVERT(datetime, Data, 105) desc;
SQLFiddle here:
http://sqlfiddle.com/#!18/475202/1
http://sqlfiddle.com/#!18/23d16/13
this logic might help.
declare #time time
set #time = '14:41'
select case
when datepart(mi, #time) between 15 and 30 then dateadd(mi, -datepart(mi, #time) + 30, #time)
when datepart(mi, #time) between 16 and 45 then dateadd(mi, -datepart(mi, #time) + 45, #time)
when datepart(mi, #time) between 46 and 59 then dateadd(mi, -datepart(mi, #time) + 60, #time)
else dateadd(mi, -datepart(mi, #time), #time) end
applying this in your query.
select Data, string_agg(Ore, ' ') as Ore
from (
select FORMAT(DataCreazione, 'dd/MM/yyyy', 'it-IT') as Data,
CONVERT(VARCHAR(5), (case
when datepart(mi, CONVERT(VARCHAR(5),DataCreazione,108)) between 15 and 30 then dateadd(mi, -datepart(mi, CONVERT(VARCHAR(5),DataCreazione,108))) + 30, CONVERT(VARCHAR(5),DataCreazione,108)))
when datepart(mi, CONVERT(VARCHAR(5),DataCreazione,108))) between 16 and 45 then dateadd(mi, -datepart(mi, CONVERT(VARCHAR(5),DataCreazione,108))) + 45, CONVERT(VARCHAR(5),DataCreazione,108)))
when datepart(mi, CONVERT(VARCHAR(5),DataCreazione,108))) between 46 and 59 then dateadd(mi, -datepart(mi, CONVERT(VARCHAR(5),DataCreazione,108))) + 60, CONVERT(VARCHAR(5),DataCreazione,108)))
else dateadd(mi, -datepart(mi, CONVERT(VARCHAR(5),DataCreazione,108))), CONVERT(VARCHAR(5),DataCreazione,108))) end), 108) as Ore
from Marcatura
where IdUtente = 2
and (Stato='Ingresso' or Stato='Uscita')
and cast(DataCreazione as DateTime)
between cast(CONVERT(VARCHAR(10), CONVERT(date, '10-11-18', 5), 23) as datetime)
and cast(CONVERT(VARCHAR(10), CONVERT(date, '10-11-19', 5), 23) as datetime)
) t
group by Data
order by CONVERT(datetime, Data, 105) desc
I have 2 queries in Oracle, one gives me information about the jobs, the other gives me a correct (amended) start time and target time to take into account the working day.
The field linking both tables is job.job_number
What I would like to do is have them together so that all the information is provided in one report, but I'm not sure how to do this.
Query 1 code
select
job.job_number,
job.job_entry_date,
job.site_code
from
job
inner join JOB_STATUS_LOG on JOB.JOB_NUMBER = JOB_STATUS_LOG.JOB_NUMBER
and job.job_log_number = job_status_log.job_log_number
inner join JOB_STATUS on JOB_STATUS.STATUS_CODE = JOB_STATUS_LOG.STATUS_CODE
where
job_status_log.allocated_officer = 'IDVE'
and job_status.status_code in ('5100','5200','5300','5400')
order by
job.job_number
Query 1 output
Job Number Job Entry Date Job Site Code
12345 01/08/2019 21:00 1234
67890 01/08/2019 18:00 5678
Query 2 Code
select
job_number,
clock_start,
case
when to_char(target_time, 'Dy', 'NLS_DATE_LANGUAGE=ENGLISH') = 'Fri'
and floor((target_time - trunc(target_time)) * 24) >= 17
then target_time + 2 + 63/24
when floor((target_time - trunc(target_time)) * 24) >= 17
then target_time + 15/24
else target_time
end as target_time
from
(
select job_number, priority_code, clock_start,
CASE
WHEN PRIORITY_CODE IN ('GC01','GC02','GC03','GC04','GC05','GC06','GC07')
THEN
clock_start + case priority_code
when 'GC01' then 1
when 'GC02' then 2
when 'GC03' then 0.5
when 'GC04' then 1
when 'GC05' then 2
when 'GC06' then 4
when 'GC07' then 24
end / 24
ELSE TARGET_COMP_DATE END as target_time
from
(
select job_number, priority_code, job_entry_date, target_comp_date,
case
when to_char(job_entry_date, 'Dy', 'NLS_DATE_LANGUAGE=ENGLISH') =
'Fri'
and floor((job_entry_date - trunc(job_entry_date)) * 24) >= 17
then trunc(job_entry_date) + 80/24
when to_char(job_entry_date, 'Dy', 'NLS_DATE_LANGUAGE=ENGLISH') =
'Sat'
then trunc(job_entry_date) + 56/24
when to_char(job_entry_date, 'Dy', 'NLS_DATE_LANGUAGE=ENGLISH') =
'Sun'
or floor((job_entry_date - trunc(job_entry_date)) * 24) >= 17
then trunc(job_entry_date) + 32/24
when floor((job_entry_date - trunc(job_entry_date)) * 24) < 8
then trunc(job_entry_date) + 8/24
else job_entry_date
end as clock_start
from job
)
)
where
priority_code in ('GC01','GC02','GC03','GC04','GC05','GC06','GC07')
Query 2 output
Job Number Clock Start Target Time
12345 02/08/2019 08:00 02/08/2019 10:00
67890 02/08/2019 08:00 02/08/2019 12:00
Required Output
This is how I would like it to appear
Job Number Job Entry Date Job Site Code Clock Start Target Time
12345 01/08/2019 21:00 1234 02/08/2019 08:00 02/08/2019 10:00
67890 01/08/2019 18:00 5678 02/08/2019 08:00 02/08/2019 12:00
One option might be to use current queries as sources for the WITH factoring clause (i.e. the CTE, Common table expression) and join them afterwards. I've shortened your queries (named q1 and q2) to make the example simpler to understand:
WITH q1 AS (SELECT job_number, job_entry_date, site_code FROM some_tables),
q2 AS (SELECT job_number, clock_start, target_time FROM another_tables)
SELECT a.job_number,
a.job_entry_date,
a.site_code,
b.clock_start,
b.target_time
FROM q1 a JOIN q2 b ON a.job_number = b.job_number
As you said that the first word has to be SELECT, no problem - switch to inline views:
SELECT a.job_number,
a.job_entry_date,
a.site_code,
b.clock_start,
b.target_time
FROM (SELECT job_number, job_entry_date, site_code FROM some_tables) a
JOIN
(SELECT job_number, clock_start, target_time FROM another_tables) b
ON a.job_number = b.job_number
I don't know which version it is nor whether it supports such joins; if not, then another option is
...
FROM (SELECT job_number, job_entry_date, site_code FROM some_tables) a,
(SELECT job_number, clock_start, target_time FROM another_tables) b
WHERE a.job_number = b.job_number
As you are basically reading your info's from the job table you might simple pass the additional data through your subselects auf Query 2. The JOINS in Query 1 are only for filtering reasons i think:
select
job_number,
job_entry_date,
site_code,
clock_start,
case
when to_char(target_time, 'Dy', 'NLS_DATE_LANGUAGE=ENGLISH') = 'Fri'
and floor((target_time - trunc(target_time)) * 24) >= 17
then target_time + 2 + 63/24
when floor((target_time - trunc(target_time)) * 24) >= 17
then target_time + 15/24
else target_time
end as target_time
from
(
select job_number, job_entry_date, site_code, priority_code, clock_start,
CASE
WHEN PRIORITY_CODE IN ('GC01','GC02','GC03','GC04','GC05','GC06','GC07')
THEN
clock_start + case priority_code
when 'GC01' then 1
when 'GC02' then 2
when 'GC03' then 0.5
when 'GC04' then 1
when 'GC05' then 2
when 'GC06' then 4
when 'GC07' then 24
end / 24
ELSE TARGET_COMP_DATE END as target_time
from
(
select job_number, priority_code, job_entry_date, target_comp_date,
case
when to_char(job_entry_date, 'Dy', 'NLS_DATE_LANGUAGE=ENGLISH') =
'Fri'
and floor((job_entry_date - trunc(job_entry_date)) * 24) >= 17
then trunc(job_entry_date) + 80/24
when to_char(job_entry_date, 'Dy', 'NLS_DATE_LANGUAGE=ENGLISH') =
'Sat'
then trunc(job_entry_date) + 56/24
when to_char(job_entry_date, 'Dy', 'NLS_DATE_LANGUAGE=ENGLISH') =
'Sun'
or floor((job_entry_date - trunc(job_entry_date)) * 24) >= 17
then trunc(job_entry_date) + 32/24
when floor((job_entry_date - trunc(job_entry_date)) * 24) < 8
then trunc(job_entry_date) + 8/24
else job_entry_date
end as clock_start
,site_code
from job
)
)
where
priority_code in ('GC01','GC02','GC03','GC04','GC05','GC06','GC07')
I wish count the rows of a table grouped by date and time intervals of 5 minutes:
for example, if the minutes portion of HH:MM falls between 00 mins and 04 min it will be counted as 00, eg. 08:04 will be counted as 08:00
if the minutes portion falls between 05 mins and 09 mins it will be counted as 05, eg. 08:06 will be counted as 08:05
Table Data
Date Time
18/01/18 08:00
18/01/18 08:01
18/01/18 08:02
18/01/18 08:03
18/01/18 08:04
18/01/18 08:05
18/01/18 08:06
18/01/18 08:08
18/01/18 08:10
19/01/18 17:01
19/01/18 17:03
19/01/18 17:04
Expected Output
DATE TIME COUNT
18/01/2018 08:00 5
18/01/2018 08:05 3
18/01/2018 08:10 1
19/01/2018 17:00 3
Table Creation
create table TAB1 (tDATE DATE,tTIME VARCHAR2(5));
Data
insert into TAB1(tDATE,tTIME) values (to_date('18/01/2018','DD/MM/YYYY'),'08:00');
insert into TAB1(tDATE,tTIME) values (to_date('18/01/2018','DD/MM/YYYY'),'08:01');
insert into TAB1(tDATE,tTIME) values (to_date('18/01/2018','DD/MM/YYYY'),'08:02');
insert into TAB1(tDATE,tTIME) values (to_date('18/01/2018','DD/MM/YYYY'),'08:03');
insert into TAB1(tDATE,tTIME) values (to_date('18/01/2018','DD/MM/YYYY'),'08:04');
insert into TAB1(tDATE,tTIME) values (to_date('18/01/2018','DD/MM/YYYY'),'08:05');
insert into TAB1(tDATE,tTIME) values (to_date('18/01/2018','DD/MM/YYYY'),'08:06');
insert into TAB1(tDATE,tTIME) values (to_date('18/01/2018','DD/MM/YYYY'),'08:08');
insert into TAB1(tDATE,tTIME) values (to_date('18/01/2018','DD/MM/YYYY'),'08:10');
insert into TAB1(tDATE,tTIME) values (to_date('19/01/2018','DD/MM/YYYY'),'17:01');
insert into TAB1(tDATE,tTIME) values (to_date('19/01/2018','DD/MM/YYYY'),'17:03');
insert into TAB1(tDATE,tTIME) values (to_date('19/01/2018','DD/MM/YYYY'),'17:04');
Whenever I need such interval I use this generic function:
CREATE OR REPLACE FUNCTION MakeInterval(ts IN TIMESTAMP, roundInterval IN INTERVAL DAY TO SECOND) RETURN TIMESTAMP DETERMINISTIC IS
denom INTEGER;
BEGIN
IF roundInterval >= INTERVAL '1' HOUR THEN
denom := EXTRACT(HOUR FROM roundInterval);
IF MOD(24, denom) <> 0 THEN
RAISE VALUE_ERROR;
END IF;
RETURN TRUNC(ts) + TRUNC(EXTRACT(HOUR FROM ts) / denom) * denom * INTERVAL '1' HOUR;
ELSIF roundInterval >= INTERVAL '1' MINUTE THEN
denom := EXTRACT(MINUTE FROM roundInterval);
IF MOD(60, denom) <> 0 THEN
RAISE VALUE_ERROR;
END IF;
RETURN TRUNC(ts, 'hh') + TRUNC(EXTRACT(MINUTE FROM ts) / denom) * denom * INTERVAL '1' MINUTE;
ELSE
denom := EXTRACT(SECOND FROM roundInterval);
IF MOD(60, denom) <> 0 THEN
RAISE VALUE_ERROR;
END IF;
RETURN TRUNC(ts, 'mi') + TRUNC(EXTRACT(SECOND FROM ts) / denom) * denom * INTERVAL '1' SECOND;
END IF;
END MakeInterval;
Valid intervals are: 1,2,3,4,5,6,10,12,15,20,30,60 SECOND, 1,2,3,4,5,6,10,12,15,20,30,60 MINUTE, 1,2,3,4,6,8,12 HOUR
You store time in a separate column which is a bad design. First, make a proper DATE or TIMESTAMP value, for example: TO_DATE(TO_CHAR(tDATE,'YYYY-MM-DD')||tTIME, 'YYYY-MM-DDHH24:MI')
Then you could use it like this
SELECT
MakeInterval(TO_DATE(TO_CHAR(tDATE,'YYYY-MM-DD')||tTIME, 'YYYY-MM-DDHH24:MI'), INTERVAL '5' MINUTE), ...
Of course, if you don't like to use a separate function you can put all in one line:
TRUNC(TO_DATE(TO_CHAR(tDATE,'YYYY-MM-DD')||tTIME, 'YYYY-MM-DDHH24:MI'), 'hh') + TRUNC(EXTRACT(MINUTE FROM TO_DATE(TO_CHAR(tDATE,'YYYY-MM-DD')||tTIME, 'YYYY-MM-DDHH24:MI')) / 5) * INTERVAL '5' MINUTE;
This is a bit cumbersome in Oracle, but quite feasible with string arithmetic:
select date,
substring(time, 1, 3) || lpad(floor(cast(substring(time, -2) as number) / 12) * 12, 2, '0') as time,
count(*)
from tab1
group by date,
substring(time, 1, 3) || lpad(floor(cast(substring(time, -2) as number) / 12) * 12, 2, '0')
order by date, time;
try this,
select tdate,
SUBSTR(ttime, 1, 2)||':'||
LPAD(NVL(DECODE(SIGN(ROUND(SUBSTR(ttime, 4, 2), -1)-SUBSTR(ttime, 4, 2)),
1, ROUND(SUBSTR(ttime, 4, 2), -1)-5,
-1, ROUND(SUBSTR(ttime, 4, 2), -1)), 0),2, '0') time_,
count(1)
from tab1
group by tdate, SUBSTR(ttime, 1, 2)||':'||
LPAD(NVL(DECODE(SIGN(ROUND(SUBSTR(ttime, 4, 2), -1)-SUBSTR(ttime, 4, 2)),
1, ROUND(SUBSTR(ttime, 4, 2), -1)-5,
-1, ROUND(SUBSTR(ttime, 4, 2), -1)), 0),2, '0');
Thank you all. As to why there is a separate VARCHAR2 column for the time component, the tables were originally migrated from some legacy database that had a date type but without a time component the latter which was stored as a string. Here is my own idea which gives me exactly what I want:
select tDATE,substr(tTIME,1,3)||
case
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 0 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 5 then '00'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 5 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 10 then '05'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 10 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 15 then '10'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 15 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 20 then '15'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 20 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 25 then '20'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 25 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 30 then '25'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 30 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 35 then '30'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 35 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 40 then '35'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 40 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 45 then '40'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 45 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 50 then '45'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 50 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 55 then '50'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 55 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 60 then '55'
else '00'
end as tTIME
,count(*)
from TAB1
group by tDATE,substr(tTIME,1,3)||
case
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 0 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 5 then '00'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 5 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 10 then '05'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 10 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 15 then '10'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 15 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 20 then '15'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 20 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 25 then '20'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 25 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 30 then '25'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 30 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 35 then '30'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 35 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 40 then '35'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 40 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 45 then '40'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 45 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 50 then '45'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 50 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 55 then '50'
when to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) >= 55 and to_number(regexp_substr(substr(tTIME,4,2),'^[-]?[[:digit:]]*\.?[[:digit:]]*$')) < 60 then '55'
else '00'
end
order by 3 desc;
SELECT *
FROM
(
SELECT stat,
SUM(DECODE(visa_country,'US',1,0)) AS USA,
SUM(DECODE(visa_country,'United Kingdom',1,0)) AS UK,
SUM(DECODE(visa_country,'Australia',1,0)) AS Australia,
SUM(DECODE(visa_country,'Canada',1,0)) AS Canada,
SUM(DECODE(visa_country,'Switzerland',1,0)) AS Switzerland,
SUM(DECODE(visa_country,'Singapore',1,0)) AS Singapore,
SUM(DECODE(visa_country,'Sweden',1,0)) AS Sweden,
SUM(DECODE(visa_country,'Netherlands',1,0)) AS Netherlands
FROM
(
SELECT *
FROM
(
SELECT stat,
visa_country,
DECODE(stat,'>= 0 '||'&'||' < 15', 1
,'>= 15 '||'&'||' < 30',2
,'>= 30 '||'&'||' < 45',3
,'>= 45 '||'&'||' < 60',4
,'>= 60 '||'&'||' < 75',5
,'>= 75 '||'&'||' < 90',6
,' >= 90',7) AS gr
FROM (
SELECT end_date,
visa_country,
CASE WHEN END_DATE between 0 and 14 THEN '>= 0 '||'&'||' < 15'
WHEN END_DATE BETWEEN 15 AND 29 THEN '>= 15 '||'&'||' < 30'
WHEN END_DATE BETWEEN 30 AND 44 THEN '>= 30 '||'&'||' < 45'
WHEN END_DATE BETWEEN 45 AND 59 THEN '>= 45 '||'&'||' < 60'
WHEN END_DATE BETWEEN 60 AND 74 THEN '>= 60 '||'&'||' < 75'
WHEN END_DATE BETWEEN 75 AND 89 THEN '>= 75 '||'&'||' < 90'
WHEN END_DATE > 90 THEN ' >= 90'
END AS stat
FROM
(
SELECT visa_country,
GREATEST(
NVL(TO_DATE(VP.WP_VALID_TILL,'DD-MON-YY'),TO_DATE(SYSDATE,'DD-MON-YY')),
NVL(TO_DATE(VP.VISA_VALID_TILL,'DD-MON-YY'),to_DATE(SYSDATE,'DD-MON-YY'))
)
- TO_DATE(SYSDATE,'DD-MON-YY') AS END_DATE
FROM visa_prac AS vp
)
) AS x
WHERE x.end_date > 0
)
) GROUP BY stat
ORDER BY gr
)
This is the code which gives the count of the employees ... But the problem here is that if any count is zero it is not showing that entire row....
Supppose no details falls in the range of >=75 & <90 then that row is not showing up..
Will be grateful for your kind help resolving it.
I think you need to remove the WHERE clause in the END
WHERE x.end_date >0
Because it is filtering out the rows in case of ZERO.
select * from
(
select stat, sum(decode(visa_country,'US',1,0))USA,
sum(decode(visa_country,'United Kingdom',1,0))UK,
sum(decode(visa_country,'Australia',1,0))Australia,
sum(decode(visa_country,'Canada',1,0)) Canada,
sum(decode(visa_country,'Switzerland',1,0))Switzerland,
sum(decode(visa_country,'Singapore',1,0))Singapore,
sum(decode(visa_country,'Sweden',1,0))Sweden,
sum(decode(visa_country,'Netherlands',1,0))Netherlands
from
(
select * FROM
(
SELECT stat,visa_country,DECODE(stat,'>= 0 '||'&'||' < 15',1,'>= 15 '||'&'||' < 30',2,'>= 30 '||'&'||' < 45',3,'>= 45 '||'&'||' < 60',4,'>= 60 '||'&'||' < 75' ,5,'>= 75 '||'&'||' < 90' ,6,' >= 90',7)gr
from (
select end_date,visa_country,case when END_DATE between 0 and 14 THEN '>= 0 '||'&'||' < 15'
when END_DATE BETWEEN 15 AND 29 THEN '>= 15 '||'&'||' < 30'
When END_DATE BETWEEN 30 AND 44 THEN '>= 30 '||'&'||' < 45'
When END_DATE BETWEEN 45 AND 59 THEN '>= 45 '||'&'||' < 60'
When END_DATE BETWEEN 60 AND 74 THEN '>= 60 '||'&'||' < 75'
When END_DATE BETWEEN 75 AND 89 THEN '>= 75 '||'&'||' < 90'
When END_DATE > 90 THEN ' >= 90'
END stat
from (select visa_country,GREATEST(nvl(TO_DATE(VP.WP_VALID_TILL,'DD-MON-YY'),to_DATE(sysdate,'DD-MON-YY')),NVL(TO_DATE(VP.VISA_VALID_TILL,'DD-MON-YY'),to_DATE(sysdate,'DD-MON-YY')))
-to_DATE(sysdate,'DD-MON-YY') AS END_DATE from visa_prac vp )
)x
)
) group by stat
order by gr
)