calculate/sum timestamp in sql - sql

I am stucking by calculating the timestamp,how can i calculate/sum on different timestamp, example as below
Time (Timestamp in one column)
***********************
0:00:01
0:00:08
0:00:12
0:00:38
0:01:04
2:04:49
15:48:38
23:30:59
7:05:52
8:17:29
I want to show the sum(timestamp) in hh:mi.Any help?

i can tel you in postgresql you can do like
postgres=# select time '05:00' - time '03:00';
?column?
----------
02:00:00
(1 row)
dont know how much this can help you

This example works on DB2 when the values being added are TIME columns (as shown in original question). The trick is to convert the times to elapsed seconds, which are much easier to add up.
WITH origTbl (origTime) AS (VALUES
( TIME( '0:00:01' ) ),
( TIME( '0:00:08' ) ),
( TIME( '0:00:12' ) ),
( TIME( '0:00:38' ) ),
( TIME( '0:01:04' ) ),
( TIME( '2:04:49' ) ),
( TIME( '15:48:38' ) ),
( TIME( '23:30:59' ) ),
( TIME( '7:05:52' ) ),
( TIME( '8:17:29' ) )
)
,
totSeconds( secs ) AS (
SELECT SUM( MIDNIGHT_SECONDS( origTime ) )
FROM origTbl
)
SELECT RTRIM( CHAR( secs/3600 ) ) || ':' ||
LPAD( RTRIM( CHAR( MOD(secs, 3600)/60 ) ), 2, '0' ) || ':' ||
LPAD( RTRIM( CHAR( MOD(secs, 60) ) ), 2, '0' ) AS totHMMSS FROM totSeconds
;
TOTHMMSS
-----------------
56:49:50
1 record(s) selected.

Related

Progress SQL : Convert Julian Date into datetime

I working for a client who uses PROGRESS database SQL (i didn't knew this kind of database, so it's my first time that i work on it).
My problem it's all the dates are in Julian-date, and i want to convert them into datetime. But i haven't found any document or help online that deals with this.
The only document i found it's:
https://knowledgebase.progress.com/articles/Article/How-to-Obtain-a-Julian-Date-in-Progress
But i want to do exactly the opposite.
For example in postgresql:
select to_timestamp(column1::text,'J')
from table1
But on PROGRESS it's harder and there is less information and examples than the others databases on the web
Thank you in advance for your help
Character
In case your Julian date is stored in a field with the character data type, you can use instr to pull it apart and then reassemble it into a timestamp:
select
-- my character field containing 92182.3966
descr,
-- get the year
floor( cast( left( descr, instr( descr, '.' ) - 1 ) as integer ) / 1000 ) as 'year',
-- get the day
mod( cast( left( descr, instr( descr, '.' ) - 1 ) as integer ), 1000 ) as 'day',
-- get the time
cast(
'0' + right( descr, length( descr ) - instr( descr, '.' ) + 1 )
as float
) as 'time',
-- combine all to timestamp
cast(
-- get first day of year
cast(
to_char(
floor( cast( left( descr, instr( descr, '.' ) - 1 ) as integer ) / 1000 )
+ 1900 -- !!! beware
)
+ '-01-01'
as date
)
-- add days
+ mod( cast( left( descr, instr( descr, '.' ) - 1 ) as integer ), 1000 )
as timestamp
)
-- add milliseconds
+ cast(
cast(
'0' + right( descr, length( descr ) - instr( descr, '.' ) + 1 )
as float
) * 86400 * 1000
as integer
) as 'timestamp'
from pub.ddcapp
where application = 'JULIAN'
This reports that the time is 1992-07-01 09:31:06.24 which is 1 second later than what your link states it was translated from.
Decimal
If on the other hand your field is a decimal, it is a lot simpler:
select
-- my decimal field containing 92182.3966
open_bal,
-- get the year
floor( open_bal / 1000 ) as 'year',
-- get the day
mod( open_bal, 1000 ) as 'day',
-- get the time
open_bal - floor( open_bal ) as 'time',
-- combine all to timestamp
cast(
cast(
to_char(
floor( open_bal / 1000 )
+ 1900 -- !!!
)
+ '-01-01'
as date
)
+ mod( open_bal, 1000 )
as timestamp
)
+ ( open_bal - floor( open_bal ) ) * 86400 * 1000
as 'timestamp'
from pub.ledbal
where adm_nr = 0

how to sum up minutes and seconds ?in oracle

I have a column called duration_d which is varchar2 and the data in that table looks like below
duration_d
-----------
12:25
01:35
12:10
04:21
12:18
12:24
I tried below query
SELECT SUM( to_date( duration_d, 'mi:ss' ))
FROM table
GROUP BY calling_number;
When I execute it following error is coming
ORA-00933: SQL command not properly ended
00933. 00000 - "SQL command not properly ended"
can any one tell me how to make sum it?
To get the total as fractions of a day you can use:
SELECT SUM( TO_DATE( duration_d, 'MI:SS' ) - TO_DATE( '00:00', 'MI:SS' ) ) AS total
FROM your_table
Which gives the result:
TOTAL
------------------------------------------
0.0383449074074074074074074074074074074074
To convert this to an interval data type you can use NUMTODSINTERVAL:
SELECT NUMTODSINTERVAL(
SUM( TO_DATE( duration_d, 'MI:SS' ) - TO_DATE( '00:00', 'MI:SS' ) ),
'DAY'
) AS total
FROM your_table
Which gives the result:
TOTAL
-------------------
+00 00:55:13.000000
Please try below:
with x as
(select sum((regexp_substr(YOUR_COLUMN, '[0-9]+', 1, 1)*60) +
regexp_substr(id, '[0-9]+', 1, 2)) seconds
from YOUR_TABLE)
SELECT
TO_CHAR(TRUNC(seconds/3600),'FM9900') || ':' ||
TO_CHAR(TRUNC(MOD(seconds,3600)/60),'FM00') || ':' ||
TO_CHAR(MOD(seconds,60),'FM00')
FROM x
Will work only if the duration is always [MI:SS].
Also you can add the group by as per your requirement.
Converting Seconds to the required duration format Reference.
Group By
with x as
(select calling_number,sum((regexp_substr(YOUR_COLUMN, '[0-9]+', 1, 1)*60) +
regexp_substr(id, '[0-9]+', 1, 2)) seconds
from YOUR_TABLE
group by calling_number)
SELECT calling_number,
TO_CHAR(TRUNC(seconds/3600),'FM9900') || ':' ||
TO_CHAR(TRUNC(MOD(seconds,3600)/60),'FM00') || ':' ||
TO_CHAR(MOD(seconds,60),'FM00')
FROM x
Use a combination of SUBSTR, to_char, to_date, NVL, INSTR, reverse and SUM.
SELECT "calling_number",
to_char(to_date(SUM(NVL(SUBSTR("duration_d", 0, INSTR("duration_d", ':')-1), "duration_d"))*60 +
SUM(substr("duration_d", - instr(reverse("duration_d"), ':') + 1)),'sssss'),'hh24:mi:ss') AS SUM_DURATION_D
FROM yourtable
GROUP BY "calling_number"
Output
calling_number SUM_DURATION_D
1 00:26:10
2 00:29:03
SQL Fiddle: http://sqlfiddle.com/#!4/9b0a81/33/0
Correct spelling as below
SELECT SUM( TO_DATE( duration_d, 'mi:ss' ) )
FROM YOURTABLE Group By calling_number

multiple row column values into single row

I have multiple row with different column values sharing the same id .
for e.g
col-A col-B col-C col-D Col-E
1 12 2012-12-01 1900-12-01 2:00:00 1900-12-01 3:30:00
2 12 2012-12-02 1900-12-01 3:00:00 1900-12-01 4:O0:00
I would like to get in single row preferably with separator ( * )
12 2012-12-01 2:00 - 3:30 * 2012-12-02 3:00 - 4:00
To avoid confusion - Edited the separator uses * instead of newline .
It is a pain to eliminate the [col-B] on the second line. The following formats the datetime's the way you seem to want them:
select [col-B],
(convert(varchar(19), [col-C] + [col-d], 121) + ' - ' +
right(convert(varchar(19), [col-E], 121), 8)
) col
from t
As noted by others, this sort of formatting is really not a database issue, but something for your application to handle. That said, and with thanks to Gordon Linoff for the conversion:
declare #TimeRanges as Table
( [col-A] Int Identity, [col-B] Int, [col-C] Date, [col-D] DateTime, [col-E] DateTime );
insert into #TimeRanges ( [col-B], [col-C], [col-D], [col-E] ) values
( 12, '20121201', '19001201 02:00:00', '19001201 03:30:00' ),
( 12, '20121202', '19001201 03:00:00', '19001201 04:00:00' ),
( 13, '20121219', '19001201 09:00:00', '19001201 17:00:00' );
select * from #TimeRanges;
select [col-A],
case when RN = 1 then Cast( [col-B] as VarChar(10) ) else '' end as [col-B], Range
from (
select [col-B], Row_Number() over ( partition by [col-B] order by [col-A] ) as RN,
( Convert( VarChar(19), [col-C] + [col-D], 121 ) + ' - ' +
Right( Convert( VarChar(19), [col-E], 121 ), 8 ) ) as Range
from #TimeRanges ) as ArbitraryPlaceholder
order by [col-A];

Convert DB2 SQL Decimal to DATE

I need to convert Decimal to date. I have a decimal date field that contains data like this :
1,132,009.00 --1/13/2009
7,152,004.00 --7/15/2004
11,012,005.00 --11/01/2005
etc
I would like it to read as xx/xx/xxxx.
Is there anyway to do this with SQL commands or DB2 logic in a select statement?
SELECT column1 from table1 ;
WITH x(decvalue) AS ( VALUES (DECIMAL(1132009.00)),(DECIMAL(7152004.00)),(DECIMAL(11012005.00)) )
SELECT CAST(
LPAD( RTRIM( CHAR( INTEGER( decvalue/1000000 ))), 2, '0' ) || '/' ||
LPAD( RTRIM( CHAR( MOD( decvalue/10000, 100 ))), 2, '0' ) || '/' ||
MOD( decvalue, 10000 )
AS CHAR(10))
AS chardateresult
FROM x
;
Using the same WITH values as #Fred, I came up with:
WITH x(decvalue) AS ( VALUES (DECIMAL(1132009.00)),(DECIMAL(7152004.00)),(DECIMAL(11012005.00)) )
SELECT TO_DATE(CHAR(CAST(decvalue AS DECIMAL(8,0))), 'MMDDYYYY')
FROM x
This assumes that your input values aren't going to be longer than 8 digits (2 for month, 2 for day, 4 for year), otherwise you'll get an overflow error on the cast. It will also fail if there's not at least some value for each of month, day, and year (00002011 would not work, for example, but 01012011 would).

Help with Sql query for comparing string(HH24MI) to date

We have a configuration table as shown below that stores the start time and the duration.
If the start time is 9:20 pm (3rd one ) add the duration then the time becomes 9:35.
I have to find out if the current time is in between any of the values.
I have to return the output based on the start_time and duration. i.e current time should be between start_time and the start_time + duration. (between 09:20 and and 09:35)
Can you please help me with the sql query or is it better if we go with sql function?
Start_time, duration(minutes) output
1108 5 2
1054 100 5
2120 15 8
I'm not a fan of storing dates and times in VARCHAR2 columns. START_TIME should really be a DATE or a TIMESTAMP column.
That said, you can do something like
with x as (
select '1108' start_time, 5 duration, 2 output from dual
union all
select '1054', 100, 5 from dual
union all
select '2120', 15, 8 from dual
)
select *
from (
select to_date(
to_char(sysdate,'YYYY-MM-DD') || ' ' ||
start_time,
'YYYY-MM-DD HH24MI' ) start_date,
to_date(
to_char(sysdate,'YYYY-MM-DD') || ' ' ||
start_time,
'YYYY-MM-DD HH24MI' ) + duration/24/60 end_date
from x)
where sysdate between start_date and end_date
The following selects all rows where sysdate is within the Start_Time and Start_Time + duration (EDITed as per comment from OP):
SELECT (TRUNC ( SYSDATE ) + TO_NUMBER ( SUBSTR ( Start_Time, 0, 2 ) ) / 24.0 + TO_NUMBER ( SUBSTR ( Start_Time, 3 ) ) / (24.0 * 60.0)) start_date, (TRUNC ( SYSDATE ) + TO_NUMBER ( SUBSTR ( Start_Time, 0, 2 ) ) / 24.0 + TO_NUMBER ( SUBSTR ( Start_Time, 3 ) ) / (24.0 * 60.0) + TO_NUMBER (duration)) end_date FROM configtable;