SQL Date and TIme - sql

I need to take the list of students with Application acceptance Date & time in University database. The report is sent on 6 PM evening to the management but the management can run it on 7 PM 8 PM or any time within the night. The application should be just 2 days ahead to the report running date.
ORACLE: I have created a query but that will give the application of entire 24 hours of a day. The problem with this query is when management runs a query on 6 PM and 8 PM , and any students are accepted in between this time. The result will be different.
select
to_char(application_accepted_date, 'DD-MON-RR:HH24:MI:SS')
from
tbl_application_accepted_date
where
to_date(application_accepted_date, 'DD-MON-rr:HH24:MI:SS') =
to_date(trunc(sysdate-2), 'DD-MON-rr:HH24:MI:SS')
;
If any application is accepted between 6 ahead I need the list in next days report. Means, I should have the list of accepted students from 6PM onwards of previous day to 5:59 application day.
I am getting application accepted after 6 PM, which I don't need in todays report, I should get this on next day report. The report is run on 4th OCT 2018

If it needs to cut off at 6pm, then just add 18/24 (18 hours) to the truncated date. You are also doing a lot of unnecessary casting. As long as application_accepted_date is a date field, then you can just compare it as a date.
select to_char(application_accepted_date, 'DD-MON-RR:HH24:MI:SS')
from tbl_application_accepted_date
where application_accepted_date >= trunc(sysdate-3)+18/24
and application_accepted_date < trunc(sysdate-2)+18/24
This will give you any applications starting at 6pm 3 days ago until just before 6pm 2 days ago.
EDIT: You could also do this with interval literals if you want. Same query as above, but more explicit in your intentions.
select to_char(application_accepted_date, 'DD-MON-RR:HH24:MI:SS')
from tbl_application_accepted_date
where application_accepted_date >= trunc(sysdate-3) + interval '18' hour
and application_accepted_date < trunc(sysdate-2) + interval '18' hour

Assuming that application_accepted_date is a DATE datatype in your data model, try this:
select
to_char(application_accepted_date, 'DD-MON-RR:HH24:MI:SS')
from
tbl_application_accepted_date
WHERE application_accepted_date BETWEEN to_date(To_char(Trunc(SYSDATE - 1),'YYYY-MM-DD')
||'18:00:00','YYYY-MM-DD HH24:MI:SS) and to_date(to_char(trunc(sysdate),'yyyy-mm-dd')||'17:59:59','yyyy-mm-dd hh24:MI:SS)
That should always return data from 6:00pm yesterday to 5:59:59pm today.

Related

How to get start & end of same week last year in DB2 using SQL?

I have a weekly report that uses these date parameters:
SELECT *
FROM TABLE
WHERE DATE_FIELD BETWEEN (CURRENT DATE - 8 DAYS) AND (CURRENT DATE - 2 DAYS)
This runs on Mondays to gather the previous week's data (Sun-Sat). What I want now is to run this for the same week of the previous year.
So for example, if the code above runs on Mon 29/06/20, it returns data from Sun 21/06/20 - Sat 27/06/20, i.e. week 26 of 2020. I want it to return data from Sun 23/06/19 - Sat 29/06/19, i.e. week 26 of 2019.
The report runs automatically so I can't just plug in the exact dates each time. I also can't just offset the date parameters to -357 and -367 days, as this gets thrown off by leap years.
I've searched for solutions but they all seem to rely on the DATEADD function, which my DB2 database doesn't recognise.
Does anyone know how I can get the result I'm looking for, please? Any advice would be appreciated! :)
The easiest way to do this is to build a calendar or dates table...(google sql calendar table)
Among the columns you'd have would be
date
year
month
quarter
dayofWeek
startOfWeek
endOfWeek
week_nbr
You can use the week() or week_iso() functions when loading the table, pay attention to the differences and pick the best fit for you.
Such a calendar table makes it easy to compare current period vs prior period.
If you assume that all years have 52 weeks, you can use date arithmetic:
SELECT *
FROM TABLE
WHERE DATE_FIELD BETWEEN (CURRENT DATE - (8 + 364) DAYS) AND (CURRENT DATE - (2 + 364) DAYS)
Because you want the week to start on a Monday, this doesn't have to take leap years into account. It is subtracting exactly 52 weeks -- and leap years do no affect weeks.
This gets more complicated if you have to deal with 52 or 53 week years.
A little bit complicated, but it should work. You may run it as is or test your own date.
SELECT
YEAR_1ST_WEEK_END + WEEKS_TO_ADD * 7 - 6 AS WEEK_START
, YEAR_1ST_WEEK_END + WEEKS_TO_ADD * 7 AS WEEK_END
FROM
(
SELECT
DATE((YEAR(D) - 1)||'-01-01')
+ (7 - DAYOFWEEK(DATE((YEAR(D) - 1)||'-01-01'))) AS YEAR_1ST_WEEK_END
, WEEK(D) - 2 AS WEEKS_TO_ADD
FROM (VALUES DATE('2020-06-29')) T(D)
);
The intermediate column YEAR_1ST_WEEK_END value is the 1-st Sat (end of week) of previous year for given date.
WEEKS_TO_ADD is a number of weeks to add to the YEAR_1ST_WEEK_END date.

How to get results from an EXACT date in MySQL? (Not an interval)

So in my query, I simply need to narrow down the results by whoever's status was last updated 3 weeks ago.
The line:
AND DATE_ADD(user_status_updated, INTERVAL - 21 DAY)
returns the results as an interval from now and 21 days from now. I am only interested in the exact date 21 days ago, but cannot find the right function to use.
I am writing automatic emails and part of this project is to check daily for users that have been inactive for 3 weeks, so it will always be a matter of NOW() minus 21 days. But I don't want the interval, I want the exact 21 days ago since last updated results.
Ok I found my solution.
WHERE user_status_updated= DATE_SUB(DATE(NOW()), INTERVAL 21 DAY)
The user_status_updated is a DATETIME field

Time elapsed between two dates (In a specific time range) ORACLE

I am creating a query that shows me the time elapsed between two dates, only taking into account only the one that is Monday through Friday from 08:00 to 17:00, for example:
For example, if a petition opens on day 1 at 6:30 p.m. and closes on day 2 at 8:45 p.m., the TMO is 45 minutes.
If it closes on day 3 at 8:45, the TMO is 9 hours and 45 minutes.
Example 2:
If a petition opens on Friday at 16:45 and closes on Tuesday at 8:30, the MTO would be: 15 minutes on Friday, nine hours on Monday and 30 minutes on Tuesday for an MTO = 9 hours 45 minutes
The query is performed on a single column of type date as I show below
I currently use a LAG function to make the query, but I can not create something functional, not even optimal to incorporate, I would greatly appreciate your help.
In the solution below I will ignore the "lag" part of your problem, which you said you know how to use. I am only showing how to count "working hours" between any two date_times (they may be during or before or after work hours, and/or they can be on weekend days; the computation is the same in all cases).
Explaining the answer in words: For two given date-times, "start" and "end", calculate how many "work" hours elapsed from the beginning of the week (from Monday 00:00:00) till each of them. This is in fact a calculation for ONE date, not for TWO dates. Then: given "start" and "end", calculate this number of hours for each of them; subtract the "end" number of hours from the "start" number of hours. To the result, add x times 5 times 9, where x is the difference in weeks between Monday 00:00:00 of the two dates. (If they are in the same week, the difference will be 0.)
To truncate a date to the beginning of the day, we use TRUNC(dt). To truncate to the beginning of Monday, TRUNC(dt, 'iw').
To compute how many "work" hours are from the beginning of the date dt until the actual time-of-day we can use the calculation
greatest(0, least(17/24, dt - trunc(dt)) - 8/24)
(the results will be in days; we calculate everything in days and then we can convert to hours). However, in the final formula we must check to see if the date is a Saturday or Sunday, in which case this should just be zero. Or, better, we can adjust the calculation a bit later, when we count from the beginning of Monday (we can use least( 5*9/24, ...)).
Putting everything together:
with
inputs ( dt1, dt2 ) as (
select to_date('2017-09-25 11:30:00', 'yyyy-mm-dd hh24:mi:ss'),
to_date('2017-10-01 22:45:00', 'yyyy-mm-dd hh24:mi:ss')
from dual
)
-- End of SIMULATED input dates (for testing only).
select 24 *
( least(5 * (17 - 8) / 24, greatest(0, least(17/24, dt2 - trunc(dt2)) - 8/24)
+ (17 - 8) / 24 * (trunc(dt2) - trunc(dt2, 'iw')))
-
least(5 * (17 - 8) / 24, greatest(0, least(17/24, dt1 - trunc(dt1)) - 8/24)
+ (17 - 8) / 24 * (trunc(dt1) - trunc(dt1, 'iw')))
+ 5 * (17 - 8) / 24 * (trunc(dt2, 'iw') - trunc(dt1, 'iw')) / 7
)
as duration_in_hours
from inputs
;
DURATION_IN_HOURS
-----------------
41.500

Count date in same day as 0

I'm try to write Oracle SQL function. Currently i try to get number of working day with cut-off point at 4.30. In problem is, how can i get the number of working day in same day as 0.
Example :
Staff opened request at 9.30 AM
Staff close the request at 4.15 (which is before cut off time)
So, the number of working day for example above should be 0 because it before cut-off time.
You could set the current day at 16.30 as a reference date and then calculate the difference between that date and the request date:
SELECT TRUNC(TO_DATE(TO_CHAR(SYSDATE,'DD-MM-RRRR') || ' 16:30','DD-MM-RRRR HH24:MI') - TO_DATE('09-12-2015 09:30','DD-MM-RRRR HH24:MI')) days
FROM DUAL

Dynamic Timestamp DB2 SQL

Using DB2 SQL
I would like to query for records since 2:00 yesterday. I want a dynamic expression that frees me from having to manually enter the current date prior to running the query. The created_datetime attribute is of timestamp dataype.
For example:
select record_key, other_stuff
from table
where created_datetime > "2 o'clock PM yesterday"
Is this kind of dynamic timestamp comparison even possible? Eventually, I'd like to be able to do a window of time, which gets complicated!
select count(1)
from table
where created_datetime between "2 o'clock PM yesterday" and "2 o'clock PM today"
I am familiar with current date, but I am trying to conceptualize how I would leverage that. The following gets me close, but it includes everything 24 hours prior to whenever the query is run.
select count(1)
from table
where created_datetime between (currentdate - 1 day) and (currentdate # 2 o'clock PM)
I know this is some pretty basic territory, and I feel guilty posting this question, but my research has not turned up anything for me so far. I appreciate every ounce of time spent on my behalf.
Try these
select record_key, other_stuff
from table
where created_datetime > CURRENT DATE - 10 HOURS
select count(1)
from table
where created_datetime between (CURRENT DATE - 10 HOURS) and (CURRENT DATE + 14 HOURS)
select count(1)
from table
where created_datetime between (CURRENT DATE - 1 DAYS) and (CURRENT DATE + 14 HOURS)
From the IBM Dev Works Library : DB2 Basics: Fun with Dates and Times
There are heaps of samples there.
E.g.
You can also perform date and time calculations using, for lack of a
better term, English:
current date + 1 YEAR
current date + 3 YEARS + 2 MONTHS + 15 DAYS
current time + 5 HOURS - 3 MINUTES + 10 SECONDS
Try this with this Timestamp option in you where clause.
Below sample to query for between last 24 hours.
select
timestamp(CURRENT date - 1 days,(CURRENT time - 24 hours)),
timestamp(CURRENT date,CURRENT time )
FROM
sysibm.sysdummy1;