Convert DB2 SQL Decimal to time
I need to convert Decimal to time. I have a decimal time field that contains data like this :
123490 --12:34:90
4506 --00:45:06
171205 --17:12:05
etc
I would like to convert into time format then i calculate min between two times columns
Is there anyway to do this with SQL commands or DB2 logic in a select statement?
To convert it to a valid time format you have to do some string manipulations like
cast( substr( right( '00' || '123456', 6) ,1,2) || ':' || substr( right( '00' || '123456', 6) ,3,2) || ':' || substr( right( '00' || '123456', 6) ,5,2) as time)
where 123456 is your decimal. This would work for your 4506 example as well.
You could of cause also use a case statement if you want to avaoid adding the "00" each time.
For calculating the difference in minues there might be other calc options.
You can check out the minutes_between function provided by Db2 11.1
You can use TO_DATE, which is short version for TIMESTAMP_FORMAT, but you first need to convert decimal to string.
select time(to_date(digits(cast(143513 as dec(6,0))),'HH24MISS')) from sysibm.sysdummy1
cast is there just to simulate 6 digit decimal
digits converts decimal to char, padding it with zeros
to_date converts string to timestamp, based on the format string. TIMESTAMP_FORMAT
time returns the time portion of a timestamp
This is based on iSeries version of DB2 but should work for LUW as well.
Related
I have a column that has number in it in the format of HHMMSS but the number is not consistent (not all have six digits), ex: "83455" "153651" "91251".
The number 83455 would mean 8:34 am and 55 as SS. I tried converting into varchar and use TO_TIME but the output is not the same as it is. Similarly, I also tried converting into timestamp then get the time from it but it just won't work. The output I want here would be 8:34:55, what is the best way to convert the number?
Try this. I split hours minutes and seconds and then concatenate them into time format.
SELECT
CAST(FLOOR(col / 10000) || ':' ||
FLOOR(MOD(col / 100, 100)) || ':' ||
MOD(col, 100) AS TIME) AS converted_time
FROM
yourtable
MOD()
An alternative approach is to use the built in function for this task.
TRY_TO_TIME().
Sometimes the built in functions are easier to read, understand, less typing, optimized (runs faster/cheaper).
SELECT
TRY_TO_TIME (DONT_WASTE, 'HH24MISS" )VOLIA
,TO_CHAR (VOLIA, 'HH12:MI:SS AM' ) AM_PM
FROM
(SELECT '83455 'DONT_WASTE UNION SELECT '153651 'UNION SELECT '91251')
The core of this problem is the format string was wrong
MM is Month, MI is minutes.
The first path I went down was slicing the string up, but the TO_TIME/TRY_TO_TIME both handle the smaller string of the pre lunchtime, but does not handle no hours, for that you might need to pad if you have such truncated values from number I assume:
select column1
,try_to_time(column1, 'HH24MMSS') as wrong
,try_to_time(column1, 'HH24MISS') as r1
,lpad(column1, 6, '0') as p
,try_to_time(p, 'HH24MISS') as r2
from values
('83455'),
('153651'),
('91251'),
('1251')
;
COLUMN1
WRONG
R1
P
R2
83455
null
08:34:55
083455
08:34:55
153651
null
15:36:51
153651
15:36:51
91251
09:00:51
09:12:51
091251
09:12:51
1251
12:00:01
null
001251
00:12:51
Thus inline it would be:
try_to_time(lpad(column1, 6, '0'), 'HH24MISS')
I want to format date in a column where date formats are mixed like d/mm/yy, d/m/yy, dd/mm/yyyy where i want ot format all values should be in one format like mm/dd/yyyy in sqlite database
SQLite does not support built-in date and/or time storage class. Instead, it leverages some built-in date and time functions to use other storage classes such as TEXT, REAL, or INTEGER for storing the date and time values.
use the TEXT storage class for storing SQLite date and time https://www.sqlitetutorial.net/sqlite-date/
This will convert month, day, year divided by slashes into year, month, day divided by dashes. For example 2/19/1921 into 1921-2-19. Just uses basic SQL with a subquery.
SELECT
surveydate
,Substr(dayyear, Instr(dayyear, '/') + 1, 999) || '-' || -- Year
month || '-' || -- Month
Substr(dayyear, 0, Instr(dayyear, '/')) -- Day
AS surveydate2
FROM (
SELECT
surveydate,
Substr(surveydate, 0, Instr(surveydate, '/')) AS month,
Substr(surveydate, Instr(surveydate, '/') + 1, 999) AS dayyear
FROM "input_locations"
)
Hello guys someone can help me converting this query to work on Oracle ?
SELECT CONVERT(VARCHAR(10),
CAST(DATEADD(DAY,CONVERT(INT,
Convert(nvarchar(50),(ASCII(SUBSTRING(A1_USERLGI,12,1)) - 50))+Convert(nvarchar(50),(ASCII(SUBSTRING(A1_USERLGI,16,1)) - 50))),
'1996-01-01') AS DATETIME),103) FROM SA1010 where A1_USERLGI <> ' ';
This code for decoding a econded field that's save user from system cod and the date of change.
Just with a few changes the Sql can be put in the Oracle flavor.
CONVERT of the date to string becomes TO_CHAR.
SUBSTRING becomes SUBSTR.
+ becomes || or CONCAT.
DATEADD of n days to a date becomes date + n
ASCII remains ASCII.
CAST works for both.
SELECT
TO_CHAR((CAST('01-JAN-1996' AS DATE) +
CAST(CONCAT((ASCII(SUBSTR(A1_USERLGI, 12, 1))-50),
(ASCII(SUBSTR(A1_USERLGI, 16, 1))-50)) AS NUMBER)), 'DD/MM/YYYY') AS dt
FROM SA1010 where A1_USERLGI <> ' ';
ORACLE APEX 4.2
I am working with Length and duration values and I'm using 3 integer fields to store hours, minutes, and seconds (Datetime didn't work for calculations). Everything works with my calculations, but I am Having trouble concatenating the values in the format HH:MM:SS to display in a report.
SELECT (Length_hour || ':' || Length_Min || ':' || Length_SEC) as "Length"
FROM TBL_VIDEO
The above works but gives me H:M:S
I'm now trying to force the first digit using TO_CHAR() like this:
SELECT (Length_hour || ':' || Length_Min || ':' || Length_SEC) as "Length", TO_CHAR(Length_Min, '01') as "Temp"
FROM TBL_VIDEO
But this gives me the following error:
Unable to bind 01 verify length of item is 30 bytes or less. Use v() syntax to reference items longer than 30 bytes. ORA-01006: bind variable does not exist
It seems as if it expects '01' to be and item to be referenced, but that's just the desired format as per TO_CHAR
Any ideas why this is happening and how I can achieve my format?
Approaching this from a completely different direction try this:
SELECT (Length_hour || ':' || Length_Min || ':' || Length_SEC) as "Length"
, regexp_substr(
to_char(
numtodsinterval(
Length_hour*3600+Length_Min*60+Length_SEC
, 'second'))
, '[^+0 ]([^.]*)'
) as "Temp"
FROM TBL_VIDEO
In this code the second column converts your numeric columns to an interval of type day to second, converts it to a string of the form +00000000 00:00:00.0000000 then uses a regular expression to pull out just the non fractional time portion (plus any days <> 0). The regexp_substr does expect that the interval is a positive and not negative value.
I am running sqlite to select data between two ranges for a sales report. To select the data from between two dates I use the following statement:
SELECT * FROM test WHERE date BETWEEN "11/1/2011" AND "11/8/2011";
This statement grabs all the dates even those outside the criteria. The date format you see entered is in the same format that I get back. I'm not sure what's wrong.
SQLite requires dates to be in YYYY-MM-DD format. Since the data in your database and the string in your query isn't in that format, it is probably treating your "dates" as strings.
Change your data to that formats to use sqlite datetime formats.
YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
HH:MM
HH:MM:SS
HH:MM:SS.SSS
now
DDDDDDDDDD
SELECT * FROM test WHERE date BETWEEN '2011-01-11' AND '2011-08-11'
One more way to select between dates in SQLite is to use the powerful strftime function:
SELECT * FROM test WHERE strftime('%Y-%m-%d', date) BETWEEN "11-01-2011" AND "11-08-2011"
These are equivalent according to https://sqlite.org/lang_datefunc.html:
date(...)
strftime('%Y-%m-%d', ...)
but if you want more choice, you have it.
SELECT *
FROM TableName
WHERE julianday(substr(date,7)||'-'||substr(date,4,2)||'-'||substr(date,1,2)) BETWEEN julianday('2011-01-11') AND julianday('2011-08-11')
Note that I use the format: dd/mm/yyyy.
If you use d/m/yyyy, Change in substr().
Or you can cast your string to Date format with date function. Even the date is stored as TEXT in the DB.
Like this (the most workable variant):
SELECT * FROM test WHERE date(date)
BETWEEN date('2011-01-11') AND date('2011-08-11')
SQLite does not have a concept of dates. It only knows them as text. When you do this in SQLite you're actually doing string comparisons. You can read more from the official documentation.
When two TEXT values are compared an appropriate collating sequence is used to determine the result.
Any numeric (i.e., not using words like 'May') format for dates that is padded and in order from biggest field to smallest field will work. "2021-05-07" (May 7th) comes before "2021-05-09" (May 9th). So if you use "yyyy-mm-dd" format then you'll be set. "yyyy/mm/dd" and "yyyymmdd" work just fine too. (For a better phrasing on "sortable" date formats check out RFC 3339 section 5.1.)
A reason to use "yyyy-mm-dd" format is because that's the format that SQLite's builtin date uses.
Special thanks to Jeff and vapcguy your interactivity is really encouraging.
Here is a more complex statement that is useful when the length between '/' is unknown::
SELECT * FROM tableName
WHERE julianday(
substr(substr(date, instr(date, '/')+1), instr(substr(date, instr(date, '/')+1), '/')+1)
||'-'||
case when length(
substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1),'/')-1)
)=2
then
substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1)
else
'0'||substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1)
end
||'-'||
case when length(substr(date,1, instr(date, '/')-1 )) =2
then substr(date,1, instr(date, '/')-1 )
else
'0'||substr(date,1, instr(date, '/')-1 )
end
) BETWEEN julianday('2015-03-14') AND julianday('2015-03-16')
Put the variable in the Where Condition and parse both dates using 'BETWEEN':
SELECT * FROM emp_master
-> if you have date formate like dd/mm/yyyy simple then,
WHERE joined_date BETWEEN '01/03/2021' AND '01/09/2021';
-> and if you have date formate like yyyy/mm/dd then,
WHERE joined_date BETWEEN '2021/03/01' AND '2021/09/01';
☻♥ Done Keep Code.
Let's say you are preparing data for some report. Then the whole ordeal will look similar to this.
--add column with date in ISO 8601
ALTER TABLE sometable ADD COLUMN DateInISO8601;
--update the date from US date to ISO8601 date
UPDATE sometable
SET DateInISO8601 = substr([DateInUSformat],length([DateInUSformat])+1, -4)
|| '-' ||
substr('00' || [DateInUSformat],instr('00' || [DateInUSformat],'/'),-2)
|| '-' ||
substr('00' || rtrim(substr([DateInUSformat],instr([DateInUSformat],'/')+1,2),'/'),-2,2);
SELECT DateInISO8601
FROM sometable
WHERE DateInISO8601 BETWEEN '2022-02-02' AND '2022-02-22';
You can of course do all that on the fly, but if you have the choice -- don't. Use the ISO date by default and convert it on the way in and out to SQLite DB.