Need hours difference in SQL query - sql

Looking for a query which can retrieve the time difference of two times. Below is the example:
EmpID EmpOnTime EmpOffTime
1 2:45 3:00
2 1:00 4:00
3 1:35 2:55
4 2:45 3:20
Result should be:
For EmpID 1 Time diffrence: 0:15
For EmpID 2 Time diffrence: 3:00
For EmpID 3 Time diffrence: 1:20
For EmpID 4 Time diffrence: 0:35
I am using the following query which giving wrong result
Query:
select offTime, onTime, (strftime('%s',offTime) - strftime('%s',onTime)) / 60 AS diffrence
from emplyoee;

This one was trickier than initially thought. Here is the SQL you will need, however your input data will need to be formatted differently to get it to work.
select EmpId,
offTime,
onTime,
time(((strftime('%s', offTime) - strftime('%s', onTime)) / 60), 'unixepoch') as difference
from employee;
I had to store the data in the YYYY-MM-DD HH:MM:SS:
2019-07-18 03:00:00
Otherwise SQLite gets confused if you mean am or pm, and the %s cannot calculate since it returns the number of seconds since 1970-01-01.

I think you can use this:
SELECT
EmpID,
time(
julianday("2000-01-01 00:00:00") +
julianday(substr("0" || EmpOffTime || ":00", 1, 8)) -
julianday(substr("0" || EmpOnTime || ":00", 1, 8))) As diff
FROM
yourTable
[SQL Fiddle Demo]
Your times need to complete with :00 at the end and sometimes with 0 at the beginning that I handle it with substr("0" || yourTime || ":00", 1, 8), then by using julianday() you can find differences of two date, and also I add julianday("2000-01-01 00:00:00") to difference to get make a valid value of time and so on.

Related

How can I truncate a timestamp to make readjustments to a date in Oracle?

I have the following query in my SELECT from Oracle:
CASE
WHEN to_char(ola.promise_date, 'D') = 2 THEN (ola.promise_date - 4)
WHEN to_char(ola.promise_date, 'D') = 3 THEN (ola.promise_date - 4)
WHEN to_char(ola.promise_date, 'D') > 3 AND to_char(ola.promise_date, 'D') < 7 THEN (ola.promise_date - 2)
WHEN to_char(ola.promise_date, 'D') = 7 THEN (ola.promise_date - 2)
WHEN to_char(ola.promise_date, 'D') = 1 THEN (ola.promise_date - 2)
END mod_Promise_date
"ola.promise_date" is a column of type TIMESTAMP, and I use the CASE statement in order to adjust the date, considering the day of the week of the original promise date (because of internal considerations of shipment, among other things)
So, for example, something that has a promise date of 2021-11-07 00:00:00.0000000 will have a modified promise date of 2021-11-05 00:00:00.0000000 (considering Sunday as the seventh day)
Now, I run this query with a program made with C#, there I have a date picker in order to select specific promise dates, so the user can choose Sunday, November 7, 2021 and it will run the query as said before, this works good with the exception of promise dates that are something like 2021-11-07 23:59:00.0000000 because the query will consider the date as 8th of November instead of 7th, and this is not expected behavior, because the hour, minutes, seconds and fractional seconds are not really needed in this specific instance of the project.
Is there a way to ignore the hour, minutes, seconds and fractional seconds in the CASE-WHEN statement? Or floor down the date to consider everything in the same day as the day specified, without consideration of the time.
I'm pretty new using Oracle, so sorry if I'm not clear enough or if the query doesn't look viable.
You can use TRUNC(datetime_value) to truncate a DATE or a TIMESTAMP data type and set the time component to midnight:
CASE TRUNC(ola.promise_date) - TRUNC(ola.promise_date, 'IW')
WHEN 0 /* Monday */ THEN TRUNC(ola.promise_date) - 2
WHEN 1 /* Tuesday */ THEN TRUNC(ola.promise_date) - 4
WHEN 2 /* Wednesday */ THEN TRUNC(ola.promise_date) - 4
WHEN 6 /* Sunday */ THEN TRUNC(ola.promise_date) - 2
ELSE TRUNC(ola.promise_date) - 2
END mod_Promise_date
Note: TO_CHAR(datevalue, 'D') will give different values depending on where you are in the world as different territories consider the week to start on different days-of-the-week. If you want a territory-agnostic method of determining the day-of-the-week then you can find the difference from the start of the ISO week using TRUNC(datetime_value) - TRUNC(datetime_value, 'IW').
If I understood you correctly, you'll just have to truncate that value and "remove" time component (i.e. reset it to midnight).
For example:
(just setting format; you don't have to do that)
SQL> alter session set nls_timestamp_format = 'dd.mm.yyyy hh24:mi:ss.ff6';
Session altered.
Query that shows the result:
SQL> select systimestamp,
2 trunc(systimestamp) result
3 from dual;
SYSTIMESTAMP RESULT
----------------------------------- -------------------
05.11.21 19:29:41,207000 +01:00 05.11.2021 00:00:00
SQL>
You'd have
... THEN (trunc(ola.promise_date) - 4)

Calculate time difference in PSQL with HH:MM splitted in several columns

I've a PSQL table like this:
Order
Start_Hour
Start_Minute
Finish_Hour
Finish_Minute
10
10
15
12
15
10
12
15
14
15
10
16
00
17
00
And I need to calculate by a query the total time expressed in hours that I spent to finish the order. In this scenario I expect to have a total of 5 hours:
12:15 - 10:15 = 2 hours
14:15 - 12:15 = 2 hours
17:00 - 16:00 = 1 hours
The query result must be 5.
The idea was concatenate start hour/minute and finish hour/minute, convert them to hour, make the difference, calculating the total.
SELECT (Start_Hour & ":" & Start_Minute) as start, (Finish_Hour & ":" & Finish_Minute) as finish
FROM OrderDetails
But when I try to convert them to HH:MM using cast or convert but I got errors.
Any advice?
Thank you
This query uses make_time as Adrian Klaver suggests.
select
"Order",
sum(extract(hour from
make_time("Finish_Hour", "Finish_Minute", 0) -
make_time("Start_Hour", "Start_Minute", 0))
) as duration
from the_table
group by "Order";
However I have remarks about your data design. Hour and minute are not enough for storing time because (apart from missing precision and other reasons) the end time might be over midnight. You have a specific data type for this - timestamp. I would suggest something like
create table the_table
(
order_nr integer,
start_time timestamp,
finish_time timestamp
);
Also note that using mixed case names in Postgresql requires double-quoting.
Use make_time:
select make_time(12, 15, 0) - make_time(10, 15, 0);
?column?
----------
02:00:00
Where in your case you would substitute in Start_Hour, Start_Minute, Finish_Hour, Finish_Minute.

Find the minute difference between 2 date time

I need to get the difference between 2 date time in minutes(Time difference in minutes). And the last difference will be calculated based on 6 PM of every date.
Sample data: need result of last column
User_Name Date Time difference in minutes
User 1 1/1/06 12:00 PM 30
user 2 1/1/06 12:30 PM 315
user 3 1/1/06 5:45 PM 15
Here the date will be always in same date and the last user date difference calculated based on default value 6PM. Assuming the dates of any user will not cross 6PM time.
Please suggest how to write the query for the same.
You could use the lead window function.
I assume your table is called mytable and the date column is mydate (it is a bad idea to call a column Date as it is a reserved word).
select user_name,
round((lead(mydate, 1, trunc(mydate)+18/24)
over (partition by trunc(mydate) order by mydate)
- mydate) *24*60) as difference
from mytable
I found the solution.. if its not correct let me know
SELECT User_name,created_date,
trunc(to_number((cast(nvl(lead (created_date,1) OVER (ORDER BY created_date),TRUNC(SYSDATE) + (19/24)) as date) - cast(created_date as date)))*24*60) as difference
FROM users;

SQL Select Count Column Between two Times

I have the database where I have two columns - date (incl. time) and minutes - as follows:
Open_Time Minute
2013-01-01 09:00:00.000 1
2013-01-01 09:01:00.000 1
2013-01-01 09:02:00.000 1
2013-01-01 09:03:00.000 1
2013-01-01 09:04:00.000 1
2013-01-01 09:05:00.000 1
How to count the minutes between the first and last date time?
select COUNT(Minute)
from test_table
where open_time between '2013-01-01 09:00:00.000' and '2013-01-01 09:05.000'
does not work for me.
I will need to count the minutes as current time - open time in the future.
Thank you for any feedback!
for mysql may be can use :
SELECT TIMESTAMPDIFF(MINUTE,'2013-01-01 09:00:00.000','2013-01-01 09:05.000') ; // return result as minutes
read here : http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
The SQL looks fine although it returns 6. Did you want that or did you want 5? You could always just start your SELECT criteria from 09:01:00.000 if that's what you want.
SQLfiddle here: http://sqlfiddle.com/#!2/d3f13/2
I am not getting exactly what you want. But if want to extract minute from your date then use following query.
SELECT EXTRACT(MINUTE FROM Open_Time) FROM test_table;
SELECT EXTRACT(MINUTE FROM Open_Time)-10 FROM test_table;
Above query will give only difference in minute. so check you DAY,HOUR,MINUTE,SECONDS based on your criteria
In sql server you can use DATEDIFF function,wich accept folowing parameters:
DATEDIFF(datepart,startdate,end date) and returns count(int) between specified date boundaries for selected datepart,so you could use something like this:
select DATEDIFF(mi,MIN(opentime),MAX(opentime)) AS 'minutes'
from test_table
where open_time between '2013-01-01 09:00:00.000' and '2013-01-01 09:05.000'
You also cloud count minutes from column "minutes",but it will be very hard to count them with current date(unless,every time when counting you insert current time in the table,or create temp table) !

absolutely NO functions surrounding a tstamp in a SQL? Hourly historical data query

I need to obtain for some specific hours data for a specific week day back to 10 weeks. The DB I work on is Oracle. I came up with the following condtions with the time stamp field:
TO_CHAR(hy.tstamp,'HH24')='10'
AND hy.tstamp > sysdate - 70
AND mod(extract ( day from sysdate-1) - extract ( day from hy.tstamp), 7) =0
Someone told me "absolutely NO functions surrounding a tstamp" (for performance reasons?). How would you to specify the conditions without operations on the time stamp field?
This sounds like the person complaining about performance has never heard of function based indexes.
Create index char_hy_stamp on my_table(to_char(hy.tstamp,'HH24'));
This should avoid the full table scan that is undoubtedly part of your explain plan. As soon as you get your sqlfiddle functioning we can go from there.
You can filter out the time slices without functions or function indexes if you join to a table of acceptable ranges. You can create one on the fly like this (note that you need the functions to create the table, but you won't need them afterward):
SELECT
TRUNC(SYSDATE + 6) - (7 * LEVEL) + INTERVAL '10' HOUR AS StartAt,
TRUNC(SYSDATE + 6) - (7 * LEVEL) + INTERVAL '11' HOUR AS EndAt
FROM DUAL
CONNECT BY LEVEL <= 10
With today's date being 5/8/2013, this will give you the following:
STARTAT ENDAT
------------------- -------------------
05/07/2013 10:00:00 05/07/2013 11:00:00
04/30/2013 10:00:00 04/30/2013 11:00:00
04/23/2013 10:00:00 04/23/2013 11:00:00
04/16/2013 10:00:00 04/16/2013 11:00:00
04/09/2013 10:00:00 04/09/2013 11:00:00
04/02/2013 10:00:00 04/02/2013 11:00:00
03/26/2013 10:00:00 03/26/2013 11:00:00
03/19/2013 10:00:00 03/19/2013 11:00:00
03/12/2013 10:00:00 03/12/2013 11:00:00
03/05/2013 10:00:00 03/05/2013 11:00:00
Now just join it to your query to get the time slices you want, and note that you don't need functions:
WITH TimeRanges AS (
SELECT
TRUNC(SYSDATE + 6) - (7 * LEVEL) + INTERVAL '10' HOUR AS StartAt,
TRUNC(SYSDATE + 6) - (7 * LEVEL) + INTERVAL '11' HOUR AS EndAt
FROM DUAL
CONNECT BY LEVEL <= 10
)
SELECT
... whatever ...
FROM your_table hy
INNER JOIN TimeRanges ON
hy.tstamp >= TimeRanges.StartAt AND
hy.tstamp < TimeRanges.EndAt
If your DB person understands that filtering on timestamp functions kills performance (unless, as Woot4Moo points out, they implement function indexes), they'll understand that the functions used to create the table of timeslices won't impact the larger query.