From what i've read so far, the data type time in sql server (starting with 2008) should be able to store the time in a HH:MM format. Then I tried this myself with the following simple exercise:
create table #mytable (id int, lat float, lon float, trajectory_id int, theTime time(5))
insert into #mytable values
('1','15.8','17.1','162','10:01'),
('2','11.5','59.7','162','10:02'),
('3','16.4','79.9','162','10:03'),
('4','29.5','10.3','180','11:12'),
('5','58.2','11.1','180','11:13'),
('6','54.5','14.1','180','11:14'),
('7','14.9','15.2','166','13:40'),
('8','15.0','13.1','166','13:42')
My expected result for the column theTime was:
theTime
10:01
10:02
10:03
11:12
11:13
11:14
13:40
13:42
What I got instead was:
theTime
10:01:00.00000
10:02:00.00000
10:03:00.00000
11:12:00.00000
11:13:00.00000
11:14:00.00000
13:40:00.00000
13:42:00.00000
Sure, I could select left(theTime, 5) and get the expected result. But i'm wondering how I could insert it directly in the desired format.
I want to use a built in function and not to store the numbers in an int for HH, MM, SS as one might have used before sql server 2005.
Using sql server 2012. Thanks
You seem confused by the difference between internal formats and display formats. TIME is a data type built into the language. When it prints out, it prints out with hours, minutes, and seconds. That is how the data type prints out, in the same way the SQL Server does not put commas in integers bigger than 1000 and uses an appropriate symbol for the decimal place. (Or for that matter prints out integers in base 10 rather than the binary format as they are actually stored.)
When you say TIME(5) you are saying that you want at least 5 decimal places of precision for fractional seconds: HH:MM:SS.SSSSS. There is no option for removing seconds altogether from the time type.
If you want to print it out in a particular format, use convert(), cast(), or format(). Happily, cast() works quite well for times. The plethora of inscrutable numeric codes for date/time are more applicable to dates, than times.
When you do left(thetime, 5) then you are implicitly converting time to a string and taking the first five characters. This seems to meet your needs. I would suggest that you just build this into your table:
alter table #mytable add thetime_hhmm as (left(thetime, 5));
Then you can use thetime_hhmm to get the value as a string with the format you want.
You can't control the format that a data type is stored as. Your time data is actually being stored as a bunch of bits -- 0's and 1's -- and it's only being displayed like 10:01:00.00000 in your query analyzer.
If you want to show it in another format, then you have to convert it to a text data type like varchar, but this is usually something your UI layer should handle, not your data layer.
Related
I have a Firebird database that saves the datetime field as a DOUBLE. I have created a ColdFusion datasource connection, so I can query the data remotely. While the rest of the data is being returned correctly, the datetime field is unreadable. I have tried using CAST and CONVERT to no avail. How can I convert this to a timestamp?
An example of the data stored is: 43016.988360
You can't just convert a DOUBLE PRECISION to a TIMESTAMP, not without explicitly defining how you want it mapped and writing that conversion yourself (or hoping there is an existing third-party UDF that does this for you).
A TIMESTAMP in Firebird is a date + time represented as an 8 byte value, where the date range is from January 1, 1 a.d. to December 31, 9999 a.d. and the time range is 00:00 to 23:59.9999 (so, 100 microsecond precision).
A DOUBLE PRECISION is - usually - the wrong type for storing date and time information, and as you haven't provided how that double value should be interpreted, we can't help you other than saying: there is no default method in Firebird to do this.
Based on the comments below, it looks like the value is a ColdFusion date value stored as double precision with the number of days since December 30th 1899, see also why is ColdFusion's Epoch Time Dec 30, 1899?. If this is really the case, then you can use the following for conversion to a TIMESTAMP:
select timestamp'1899-12-30 00:00' + 43016.988360 from rdb$database
Which will yield the value 2017-10-08 23:43:14.304. Using the value 43182.4931754 from the comments will yield 2018-03-23 11:50:10.354. That is a millisecond off from your expectation, but that might be a rounding/presentation issue, eg I get the exact expected date if I use 43182.49317539 instead.
I would strongly suggest you carefully test this with known values.
Working with an Access database, using SQL commands to pull data from it. I have a column 'Duration' formatted in smalldatetime, which contains data pertaining to the duration of a phone call. The data is this column is like so
0/01/1900 12:00:26 AM
This indicates a call that is 26 seconds in duration. (all start at 12:00:00 AM and work upwards)
I have a column called 'Extension' which identifies the user of the phone.
I am wanting to run a query that will show me total durations, but grouped by extensions.
The query I have so far is
SELECT (CONVERT(VARCHAR(8),(DATEADD(ms, SUM(DATEDIFF(ms, '00:00:00.000', (CONVERT(VARCHAR(8),Duration,108)))), '00:00:00.000')),108)) as "timetest",
Extension AS Extension
FROM BrendanTest GROUP BY Extension
This shows:
Timetest Extension
00:12:00 117
00:06:00 118
which is correct.
However, I want to format the result, to show in decimal minutes, for example
00:04:56
would become
4.93
Is there a way I can do this? Thanks a lot for the help!
Assuming '00:04:56' is in the format HH:MM:SS, you can try something like the below to convert it to decimal format:
SELECT PARSENAME(REPLACE('00:04:56',':','.'),3) * 60 --Convert the hours to minutes
+ PARSENAME(REPLACE('00:04:56',':','.'),2) --Add converted hours to minutes
+ CONVERT(FLOAT, LEFT((CONVERT(INT,(PARSENAME(REPLACE('00:04:56',':','.'),1)))/0.6),2))/100 -- convert to decimal format
I want to use Like operator in a column of datetime. The values of the column is as follows:
2013-08-31 17:54:52.000
2013-08-31 17:54:52.000
My query is as below:
SELECT * FROM table where created_date Like '%54%'
It works fine. but when I search for '%52%' instead of '%54%', it gives me nothing. (It is working when I search till the minutes, but when I search for seconds or milli seconds it does not work.)
I have looked at the following url and it is working
SQL LIKE Statement on a DateTime Type
I want to know the reason, why this is happening and how like operator works with datetime type column.
I think it would be a better idea to use the DATEPART operator of SQL SERVER to extract the portion of date.
And example could be like:-
SELECT * FROM table
where DATEPART(minute,created_date)=54
EDIT:-
I want to know the reason, why this is happening and how like operator
works with datetime type column.
Actually there is no direct support given by SQL Server for LIKE operator for DATETIME variable but you can always cast the DATETIME to a VARCHAR and then try to use the LIKE operator as you want.
On a side note:-
MSDN says:-
DATEPART can be used in the select list, WHERE, HAVING, GROUP BY and
ORDER BY clauses.
In SQL Server 2012, DATEPART implicitly casts string literals as a
datetime2 type. This means that DATEPART does not support the format
YDM when the date is passed as a string. You must explicitly cast the
string to a datetime or smalldatetime type to use the YDM format.
The 'LIKE' operator and any regular expression operators provided by other databases are used to process text values. A date is definitely not a text value, it is a separata type by itself.
It makes little sense to apply a text operator to a non-text type (like int or DATETIME or DATETIMEOFFSET), which is why you can't use LIKE on dates in any database. First of all, the values are not stored as text but in an implementation-specific binary form.
Then, while you can use LIKE on a specific text representation of a date, eg using CAST you have to absolutely certain what that representation is. Different locales display dates differently, with year first, year last, month first or last or whatever. What would you search against?
Moreover, what is 54? 54 minutes, 54 seconds or 654 milliseconds?
The only sensible solution is to use DATEPART to check specific parts of a date, or the BETWEEN operator to check for ranges.
I have to run column checks for data consistency and the only thing that is throwing off my code is checking for character lengths for dates between certain parameters.
SEL
sum(case when ( A.date is null or (character_length(A.date) >8)) then 1 else 0 end ) as Date
from
table A
;
The date format of the column is YYYY-MM-DD, and the type is DA. When I run the script in SQL Assistant, I get an error 3580 "Illegal use of CHARACTERS, MCHARACTERS, or OCTET_LENGTH functions."
Preliminary research suggests that SQL Assistant has issues with the character_length function, but I don't know how to adjust the code to make it run.
with chareter length are you trying to get the memory used? Becuase if so that is constant for a date field. If you are trying to get the length of the string representation i think LENGTH(A.date) will suffice. Unfortanatly since teradata will pad zeros on conversions to string, I think this might always return 10.
UPDATE :
Okay so if you want a date in a special 'form' when you output it you need to select it properly. In teradata as with most DBs Date are not store in strings, but rather as ints, counting days from a given 'epoch' date for the database (for example the epoch might be 01/01/0000). Each date type in teradata has a format parameter, which places in the record header instructions on how to format the output on select. By default a date format is set to this DATE FROMAT 'MM/DD/YYYY' I believe. You can change that by casting.
Try SELECT cast(cast(A.date as DATE FORMAT 'MM-DD-YYYY') as CHAR(10)) FROM A. and see what happens. There should be no need to validate the form of the dates past a small sample to see if the format is correct. The second cast forces the database to perform the conversion and use the format header specified. Other wise what you might see is the database will pass the date in a date form to SQL Assitant and sql assitant will perform the conversion on the application level, using the format specified in its own setting rather then the one set in the database.
I have a column that comes into my SQL database as a varchar(10), but looks like HH:MM:SS. The column name is runTime.
I need to convert that column to seconds and do some calculations with it and another colunm called totalItems. totalItems is an int data type. An example of one calculation would be:
totalItems/runTime
So, it appears as though I need to convert runTime to a decimal, and then use it in the calculation, but when I can't do that without first converting the time to seconds, or I get an error (due to the ":").
So, how can I possibly convert the sessionRunTime into seconds first, and then convert those seconds to a decimal data type, then do the calculation from there? One example might be 59222 totalItems and 04:15:17 for runTime.
If there's a better way to handle this, I'm certainly open to that as well. Thanks!
So long as the hours portion doesn't match or exceed 24, you can convert to a datetime and use the built in functions to work out how long the time is in seconds:
select DATEDIFF(second,'00:00:00',CONVERT(datetime,'04:15:17'))
15317
If you need to do maths with this result, and the other value is an int, then multiple one or other of the values by 1.0 to force the maths to be done as floats, if that's required.
You can cast to datetime and use datediff to convert your string to seconds.
select datediff(second, 0, cast('04:15:17' as datetime))
Result:
15317