Dividing a date value in T-SQL - sql-server

I am working on migrating an Access program into SQL Server.
The following is my SQL code taken directly from access.
(([Promise Date])-([Date Recieved]))/100
As you can see, I am attempting to do a division on a datetime value.
This is the error message i receive:
Msg 257, Level 16, State 3, Line 1
Implicit conversion from data type datetime to int is not allowed. Use the
CONVERT function to run this query.
Both fields are type Datetime. Any ideas what I am missing?

I think if I am right you are looking for something like this
SELECT DATEDIFF(day, [Promise Date], [Date Recieved])/100;
If right you can get more details here

since dates in access are effectively stored as DOUBLE, I would recommend converting to the SQL float type to handle any part days
(cast([Promise Date] as float) - cast([Date Recieved] as float))/100
check out the following example, the different ideas here give quite different answers
declare #x as datetime = '19960420 15:05:48';
declare #y as datetime = '19960423 18:09:23';
select (CAST(#y as float) - CAST(#x as float)) / 100
select (CAST(#y as int) - CAST(#x as int)) / 100
select datediff(day,#x,#y) / 100
select cast(datediff(day,#x,#y) as float) / 100
Access should treat the dates as floats, with the fractional part representing time, and the integer part representing days

Declare #pd Date = '2019-01-15'
Declare #dr Date = '2019-01-12'
Select Cast(DATEDIFF(d,#dr,#pd) As Float) /100
Result
0.03
UPDATE: As per Cato's comment to allow for DateTime
Declare #pd DateTime = '2001-01-01 19:00:00'
Declare #dr DateTime = '2001-01-05 13:00:00'
Select (Cast(DATEDIFF(hh,#dr,#pd) As Float)/24) / 100
Result:
-0.0375

Related

Cast or convert DD-MON-YYYY AM/PM to YYYY-MM-DD

I'm stuck in finding an answer on how to convert:
07-DEC-18 01.00.54.984000 PM to 2018-12-07 13.00.54.984000
I think the time of 01.00.54 PM is 13hours , 0 minutes and 54 seconds
I have try to convert with 112 but still i can't find out how to cast or convert this.
Below is one method that converts the date and time portions separately, and then uses DATEADD to combine the results. This assumes the actual time precision is not greater than milliseconds. Note that you need to use datetime2 instead of datetime to avoid rounding to 1/300 milliseconds.
DECLARE #DateTimeString varchar(30) = '07-DEC-18 01.00.54.984000 PM';
SELECT DATEADD(
millisecond
, DATEDIFF(millisecond, '', CAST(REPLACE(SUBSTRING(#DateTimeString, 11, 8), '.', ':') + RIGHT(#DateTimeString, 10) AS time))
, CAST(LEFT(#DateTimeString, 9) AS datetime2)
);
This converts your value to the datatype it should be, a datetime2(6). Date and time datatypes don't have formats, if you're storing them in a particular format you're doing it wrong (as it means you're storing the value as a varchar).
DECLARE #YourDate varchar(30) = '07-DEC-18 01.00.54.984000 PM';
SELECT V.YD,
TRY_CONVERT(datetime2(6),F.FormatedYD,106)
FROM (VALUES(#YourDate)) V(YD)
CROSS APPLY (VALUES(STUFF(STUFF(V.YD,13,1,':'),16,1,':'))) F(FormatedYD);
If this was a table, then I would fix your actual column datatype by doing the following:
UPDATE YT
SET YourDateColumn = CONVERT(varchar(30),TRY_CONVERT(datetime2(6),F.FormatedYD,106),126)
FROM YourTable YT
CROSS APPLY (VALUES(STUFF(STUFF(YT.YourDateColumn,13,1,':'),16,1,':'))) F(FormatedYD);
ALTER TABLE YourTable ALTER COLUMN YourDateColumn datetime2(6);

Adding two time fields together

I have two columns within my table they are set as nvarchar fields but contain time values.
one column is a time field one is the duration field
eg.
Time 1 = 15:05:22 (time field)
Time 2 = 00:02:00 (duration field)
I want to output Time 1 + Time 2 = 15:07:22
I have tried CAST(time1 as datetime)+CAST(time2 as datetime)
but I get 1900-01-01 15:07:22.000, and I don't want the date part. I can't use cast as time as I get an error I presume this is because the fields are set as nvarchar and not date/time?
Just cast the result to time to get rid of the date portion:
DECLARE #time_txt varchar(8);
DECLARE #duration_txt varchar(8);
SET #time_txt = '15:05:22';
SET #duration_txt = '00:02:00';
SELECT CAST(CAST(#time_txt as datetime) + CAST(#duration_txt as datetime) as time);
-- yields the time value 15:07:22.0000000
If you need this as a string (for example, in hh:mm:ss format), you can use CONVERT with the appropriate format option:
...
SELECT CONVERT(varchar(8), CAST(#time_txt as datetime) + CAST(#duration_txt as datetime), 108);
-- yields the string 15:07:22
PS: In general, you should use time columns for time values instead of varchar columns. Unfortunately, SQL Server does not have a really good data type for durations (time spans).
select dateadd(second,datediff(second,0,time1),time2) as Time3
from your_table

How to convert int year into valid date format in my stored procedure

My stored proc has the following select statement:
select Name,Holiday from tblNames where ID = #ID and DATENAME(YEAR, GETDATE()) = #Year
When executing the statement I have an error
"Error converting data type int to nvarchar."
How can I convert #Year parameter to a correct year?
The return type of the datename function is nvarchar, you want the datepart function that returns an integer value, so change to DATEPART(YEAR, GETDATE()) instead.
datename is what you would use to get the name of a month or weekday.
Or you could use the year(getdate()) function instead as Gordon L mentioned in a comment.
I'd recommend to switch back from fixing specific error message to the original question. You have a date in your table and need to filter it by range. So just provide to server the range bounds. This will also avoid any conversions of stored data. To avoid tail time issue you may append '23:59:59.997' to the upper bound of range or (my advice) provide next date and compare by < instead of <=
set #startdate = ...
set #enddate = dateadd(dd, 1, ...)
select *
from mytable
where t.date >= #startdate and t.date < #enddate
Complicated conversions can make it impossible to use appropriate index. If you can convert your arguments and provide prepared values to server - strive to do so.

Error when converting float to datetime

I am trying to convert a float in the format yyyymmdd to datetime. According to this the correct style code for that format is 112.
Code:
select
convert(datetime,cast(myDate as numeric),112)
from MyTable
Error:
Msg 8115, Level 16, State 2, Line 1
Arithmetic overflow error converting expression to data type datetime.
I get the same error without the cast as numeric part. I've been looking around for a couple hours, but I haven't been able to find anything that fixes this. If you know a better way to convert the float to a datetime I would be open to that idea.
Thank you for your help.
EDIT
Here is the working code:
SELECT
case when isdate(CAST(CAST(myDate AS INT) AS VARCHAR(8))) = 1
then CAST(CAST(CAST(myDate AS INT) AS VARCHAR(8)) AS DATETIME)
end
from MyTable
I wrapped it in the isdate because there were a few invalid dates in there. Thanks to Matt for the help.
EDIT2
Better version:
SELECT
TRY_CAST(CAST(CAST(myDate AS INT) AS VARCHAR(8)) AS DATETIME)
FROM MyTable
First you must convert the FLOAT to a VARCHAR. And since FLOAT has a number of decimal points, it must first be converted to an INT.
DECLARE #myDate FLOAT
SET #myDate = 20140721
SELECT CAST(CAST(#myDate AS INT) AS VARCHAR(8))
--20140721
Then you can convert the VARCHAR to DATE or DATETIME format.
DECLARE #myDate FLOAT
SET #myDate = 20140721
SELECT CAST(CAST(CAST(#myDate AS INT) AS VARCHAR(8)) AS DATE)
--2014-07-21

Arithmetic overflow error converting expression to data type datetime. (while displaying date time..)

While executing following error is showing
declare #yr_mnth_dt as numeric;
set #yr_mnth_dt = 20130822;
select convert(datetime,#yr_mnth_dt,112) as YR_MNTH_DT
error shows
Arithmetic overflow error converting expression to data type datetime.
You issue is that you're trying to convert the numeric to a datetime, and this just isn't working.
You need to turn your numeric into a string first:
declare #yr_mnth_dt as numeric;
set #yr_mnth_dt = 20130822;
select yr_mnth_dt = cast(cast(#yr_mnth_dt as char(8)) as datetime);
SQL Fiddle with demo.
When you try and convert a numeric type to a datetime, SQL Server tries to add the numeric value as the number of days to the date 01-Jan-1900. In your case this is trying to add millions of days, and hence the overflow error.
CONVERT works fine, too, if you prefer:
select yr_mnth_dt = convert(datetime, convert(char(8), #yr_mnth_dt));
SQL Fiddle with demo.
I've only seen the conversion used for strings. I can't easily tell whether it's even designed to work with numbers. You could convert the number to a string, then the string to a date. However, I would personally just use DATEFROMPARTS:
SELECT DATEFROMPARTS(#yr_mnth_dt / 10000,
(#yr_mnth_dt / 100) % 100,
#yr_mnth_dt % 100) AS YR_MNTH_DT
Why numeric?
Try this
declare #yr_mnth_dt as varchar(10);
set #yr_mnth_dt = '20130822';
select convert(datetime,#yr_mnth_dt,112) as YR_MNTH_DT

Resources