Incrementing hours and days - sql

I am building a report in SSRS.
In design mode it looks like this:
tat2 are values 1 through 192 and appear on the report like this:
1
2
3
...
192
I would like to know if there's a way to instead do something like this:
DAY 1 12:00AM
DAY 1 1:00AM
DAY 1 2:00AM
...
DAY 7 9:00PM
...
DAY 8 12:00AM
In other words, I would like to turn the numbers 1 through 192 into hours and days.

You could use Date.AddHours() for this - just create a new Date that's the start of any year and use
Date.AddHours(Fields!YourNumericField.Value)
This way you get rolling hours - will you ever have more than 192? What's the maximum range, as this would roll-over at 365. You could just mix and match and do an expression though like:
=Math.Ceiling(Fields!YourNumericField.Value / 24) & SomeDate.AddHours(Fields!YourNumericField.Value)
Something like that
I don't have SSRS on this machine to test though :P
Edit:
Ok so to get the base date you can use new DateTime(year, month, day)
http://msdn.microsoft.com/en-us/library/system.datetime.aspx
So the expression
="DAY " & Math.Ceiling(Fields!tat2.Value / 24) & " " & format(new DateTime(2000, 1, 1).AddHours(Fields!tat2.Value), "hh:mm tt")
This should give:
DAY 1 10:45 AM
Should work - if you want to change the format of the 10:00AM bit check this reference:
http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
"HH:mm" gives you 24 hour time + minutes e.g. 23:54
"hh:mm tt" is 12 hour e.g. 12:00 PM
Have a play

This can be easily done in the underlying query - not sure about doing it in SSRS:
SELECT
Tat2 / 24 + 1 as Day,
CAST(Tat2 % 24 AS CHAR(2)) + ':00 ' +
CASE WHEN Tat2 % 24 > 12 then 'PM' else 'AM' end as AMPM
FROM YourTable
This won't, of course, handle more than 365 days, because it doesn't months or years.

Related

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.

Finding the best way to pull the last 7 days with Impala when datetime is string

I am trying to work with a dataset that we started pulling in and of course the "devicereceipttime" is stored as a string, and I cant convince anyone to change it right now. However the "year", "month", "day" and "hour" are broken out into separate fields as "ints". It looks like the following:
devicereceipttime(string) year(int) month(int) day(int) hour(int)
2018-06-19T05:00:06.265Z 2018 6 19 5
2018-06-19T18:53:56.776Z 2018 6 19 6
2018-06-19T02:10:05.252Z 2018 6 19 2
2018-06-19T12:14:01.395Z 2018 6 19 12
I am using Impala and would like to run a query similar to the one below but one that would work with the types above either just using the "devicereceipttime" string value or the "y/m/d" ints. I am looking to capture a whole week(7 consecutive days) so I will probably schedule reports to run in CDSW on Saturdays or Mondays.
This a query I was using when the datetime string format was "yyyy-mm-dd hh:mm:ss"
select *
from winworkstations_realtime
where devicereceipttime BETWEEN concat(to_date(now() - interval 1 days), " 00:00:00") and concat(to_date(now() - interval 8 days), " 24:00:00")
Would it be better to use the string or try to figure it out with a bunch of ints?
I came up with this to satisfy the query:
devicereceipttime BETWEEN concat(to_date(now() - interval 7 days), "T00:00:00.000Z") and concat(to_date(now() - interval 1 days), "T23:59:59.999Z")
select w.destinationhostname,w.destinationusername, w.destinationprocessname, count(*) as count \
from winworkstations_realtime w \
where w.devicereceipttime BETWEEN concat(to_date(now() - interval 7 days), "T00:00:00.000Z") and concat(to_date(now() - interval 1 days), "T23:59:59.999Z") AND w.externalid="4688" AND w.destinationhostname like "T%" AND (w.destinationusername not like "%$" AND w.destinationusername not like "LOCAL%" AND w.destinationusername not like "-") \
group by w.destinationhostname, w.destinationusername,w.destinationprocessname \
order by 1,2'

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

How to convert and display an Integer into YYYYMMDD format using Select query without neglecting days and leap year logic?

I have a query to retrieve a set of non null records from a column x consisting of DATE format.
If count(x) = 35 then i need to display the value as 1 Month & 5 days
If 369 days then 1 year & 4 days or If 400 days then 1 year 1 month 5 days respectively
Query: In the above instance,unfortunately i am neglecting 0.25 days but How to tweak my actual requirement in such a way that i don't end up neglecting days and handle leap year logic too
How to solve this issue?
it is not clear if you need of a time's generic computing in years, months and days, based on averages of number of days of a month, etc.. or if you want an exact compute of the number of the months that pass starting froma adate.. for example if your total sum of 400 days start from 15 march, then the month is counted by 1 after, let's say, 15 days, and so the remaining days are 20.. I don't know if I explained..
In the first hypotesis, you may use the following pseudo-coded solution, that is a very approximative method..
however, if you know a start date, it is possible to compute exactly how many "bissextile" days are comprehended between your interval of days starting from your start date
let's say to have output variables Years, Months, Days .. and an input totalDaysdays assigned with your data retrieved from the db, then:
(pseudocode)
Years = trunc((totalDays / 365)
bissextileDays = trunc((totalDays / 365) / 4)
numDaysOffset = (totalDays Mod 365) + bissextileDays
Months = trunc(numDaysOffset / 30)
Days = numDaysOffset Mod 30
Actually i found something that will suit my requirement.
https://community.oracle.com/thread/2587161?start=0&tstart=0
select days,
floor(days / 365.25) years,
floor(mod(days,365.25) / (365.25 / 12)) months,
round(mod(days,365.25 / 12)) days
from periods
So this can produce expected output when number is given. This produces output as years,months and remaining days

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;