SQL HELP... CONVERT(int, CONVERT(datetime, FLOOR(CONVERT(float, getdate()))) - sql

I am having a problem adjusting this part of my SQL statement:
HAVING dbo.BOOKINGS.BOOKED = CONVERT(int, CONVERT(datetime,
FLOOR(CONVERT(float, GETDATE()))) + 2)
Normally, the page that uses this statement just lists the amount of sales for today, I want to switch the GETDATE() to a date that I declare. I tried all different formats and none have worked

Use the DATEADD/DATEDIFF method of setting the time portion to midnight of the current date - it's the fastest means, and casting to FLOAT can be unreliable:
HAVING BOOKINGS.dbo.BOOKED = CONVERT(INT, DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0))+2
Then, you can set your own date easily if you use a variable (#var in this example, within a stored procedure or function):
DECLARE #var DATETIME
SELECT ...
HAVING BOOKINGS.dbo.BOOKED = CONVERT(INT, DATEADD(dd, DATEDIFF(dd, 0, #var), 0))+2
This assumes #var is a DATETIME data type. Otherwise, you'll need to use a date format SQL Server will implicitly convert to a DATETIME -- or use CAST/CONVERT to explicitly convert the value.

if you want you to give your own date you could do this instead of getdate() which gives current system timestamp.
Cast('2010-11-04 13:28:00.000' as datetime)

How about
declare #myDate as datetime
set #myDate = '11/2/2010'
. . .
HAVING dbo.BOOKINGS.BOOKED = CONVERT(int, CONVERT(datetime,
FLOOR(CONVERT(float, #myDate ))) + 2)
That should do it, and it should automatically do the type conversion on your date string used in the set statement, or you could just pass in a datetime parameter if this is in a stored procedure.

Related

Is there a way to preserve locale when format a datetime in SQL? [duplicate]

I have an sql DateTime (ms sql server) and want to extract the same date without the seconds:
e.g. 2011-11-22 12:14:58.000 to become: 2011-11-22 12:14:00.000
How can I do this? I was thinking to use DATEADD in combination with DATEPART but seems very error prone (besides performance issues)
SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, yourcolumn), 0) FROM yourtable
This will be effective, if you don't want a slow conversion between datatypes.
For a solution that truncates using strings try this:
SELECT CAST(CONVERT(CHAR(16), GetDate(),20) AS datetime)
CHAR(16) works only if our variable is converted to ODBC canonical format, as shown above by using 20 as the format specifier.
DECLARE #date DateTime = '2011 Nov 22 12:14:55';
SELECT CONVERT(Char(16), #date ,20) AS datetime
Results:
| datetime |
|------------------|
| 2011-11-22 12:14 |
Then you simply cast back to a DateTime type to continue using the value.
NOTE: This is only viable for data types that do not carry TimeZone info.
Also type conversions to VarChar and back are usually LESS performant than using DateTime functions that use numeric operations internally.
Consider other solutions posted if performance is a concern or if you must retain timezone information.
DECLARE #TheDate DATETIME
SET #TheDate = '2011-11-22 12:14:58.000'
DATEADD(mi, DATEDIFF(mi, 0, #TheDate), 0)
In queries
/* ...all records in that minute; index-friendly expression */
WHERE TheDate BETWEEN DATEADD(mi, DATEDIFF(mi, 0, #TheDate), 0)
AND DATEADD(mi, DATEDIFF(mi, 0, #TheDate) + 1, 0)
Date and time needs carefully and not being converted as TEXT.
My personal solution:
CREATE FUNCTION [dbo].[fnDateTimeTruncated]
(
#datetime DATETIME
)
RETURNS DATETIME
AS
BEGIN
RETURN DATETIMEFROMPARTS ( year(#datetime), month(#datetime), day(#datetime), DATEPART(hh,#datetime), DATEPART(mi,#datetime), 0, 0)
END
Edited:
Regarding http://blog.waynesheffield.com/wayne/archive/2012/03/truncate-a-date-time-to-different-part/, DateAdd has a better performance.
Thanks to t-clausen.dk
With a little fiddling around, this seems to work well:
SELECT CAST(CONVERT(CHAR(17), bl.[time],113) AS varchar(17))
Result given: 2011-11-22 12:14
The exact way I'm using it in my query as part of the selection list :
,CAST(CONVERT(CHAR(17), bl.[time],113) AS varchar(17))
+ ' (UTC +0)' AS [TIME]
Gives me the result: 15 Dec 2017 06:43 (UTC +0)
From SQL Server 2014, You can use Format function for this.
for Ex.
declare #Startdate datetime = '2020-11-07 15:27:50.713'
set #Startdate = Convert(datetime,FORMAT(#Startdate, 'yyyy-MM-dd HH:mm'))
> Result is
2020-11-07 15:27:00.000
If there is no milliseconds, than
DECLARE #dt datetime2 = '2011-11-22 12:14:58.000';
DECLARE #goalDt datetime2 = DATEADD(second,-DATEPART(second,#dt), #dt);
To remove a milliseconds part, add
SET #goalDt = DATEADD(millisecond,-DATEPART(millisecond,#goalDt ), goalDt dt);
To Round Off it:
DECLARE #TheDate DATETIME;
SET #TheDate = '2019-1-2 12:14:58.400';
SELECT CAST(#TheDate AS SMALLDATETIME);
To just Truncate:
DECLARE #TruncTheDate DATETIME;
SET #TruncTheDate = '2019-1-2 12:14:58.400';
SELECT DATEADD(mi, DATEDIFF(mi, 0, #TruncTheDate), 0);
select substring(cast(cast(getdate() as time(0)) as char(8)),0,6)

Combining (concatenating) date and time into a datetime

Using SQL Server 2008, this query works great:
select CAST(CollectionDate as DATE), CAST(CollectionTime as TIME)
from field
Gives me two columns like this:
2013-01-25 18:53:00.0000000
2013-01-25 18:53:00.0000000
2013-01-25 18:53:00.0000000
2013-01-25 18:53:00.0000000
.
.
.
I'm trying to combine them into a single datetime using the plus sign, like this:
select CAST(CollectionDate as DATE) + CAST(CollectionTime as TIME)
from field
I've looked on about ten web sites, including answers on this site (like this one), and they all seem to agree that the plus sign should work but I get the error:
Msg 8117, Level 16, State 1, Line 1
Operand data type date is invalid for add operator.
All fields are non-zero and non-null. I've also tried the CONVERT function and tried to cast these results as varchars, same problem. This can't be as hard as I'm making it.
Can somebody tell me why this doesn't work? Thanks for any help.
Assuming the underlying data types are date/time/datetime types:
SELECT CONVERT(DATETIME, CONVERT(CHAR(8), CollectionDate, 112)
+ ' ' + CONVERT(CHAR(8), CollectionTime, 108))
FROM dbo.whatever;
This will convert CollectionDate and CollectionTime to char sequences, combine them, and then convert them to a datetime.
The parameters to CONVERT are data_type, expression and the optional style (see syntax documentation).
The date and time style value 112 converts to an ISO yyyymmdd format. The style value 108 converts to hh:mi:ss format. Evidently both are 8 characters long which is why the data_type is CHAR(8) for both.
The resulting combined char sequence is in format yyyymmdd hh:mi:ss and then converted to a datetime.
The simple solution
SELECT CAST(CollectionDate as DATETIME) + CAST(CollectionTime as DATETIME)
FROM field
An easier solution (tested on SQL Server 2014 SP1 CU6)
Code:
DECLARE #Date date = SYSDATETIME();
DECLARE #Time time(0) = SYSDATETIME();
SELECT CAST(CONCAT(#Date, ' ', #Time) AS datetime2(0));
This would also work given a table with a specific date and a specific time field. I use this method frequently given that we have vendor data that uses date and time in two separate fields.
Cast it to datetime instead:
select CAST(CollectionDate as DATETIME) + CAST(CollectionTime as TIME)
from field
This works on SQL Server 2008 R2.
If for some reason you wanted to make sure the first part doesn't have a time component, first cast the field to date, then back to datetime.
DECLARE #ADate Date, #ATime Time, #ADateTime Datetime
SELECT #ADate = '2010-02-20', #ATime = '18:53:00.0000000'
SET #ADateTime = CAST (
CONVERT(Varchar(10), #ADate, 112) + ' ' +
CONVERT(Varchar(8), #ATime) AS DateTime)
SELECT #ADateTime [A nice datetime :)]
This will render you a valid result.
Solution (1): datetime arithmetic
Given #myDate, which can be anything that can be cast as a DATE, and #myTime, which can be anything that can be cast as a TIME, starting SQL Server 2014+ this works fine and does not involve string manipulation:
CAST(CAST(#myDate as DATE) AS DATETIME) + CAST(CAST(#myTime as TIME) as DATETIME)
You can verify with:
SELECT GETDATE(),
CAST(CAST(GETDATE() as DATE) AS DATETIME) + CAST(CAST(GETDATE() as TIME) as DATETIME)
Solution (2): string manipulation
SELECT GETDATE(),
CONVERT(DATETIME, CONVERT(CHAR(8), GETDATE(), 112) + ' ' + CONVERT(CHAR(8), GETDATE(), 108))
However, solution (1) is not only 2-3x faster than solution (2), it also preserves the microsecond part.
See SQL Fiddle for the solution (1) using date arithmetic vs solution (2) involving string manipulation
Concat date of one column with a time of another column in MySQL.
SELECT CONVERT(concat(CONVERT('dateColumn',DATE),' ',CONVERT('timeColumn', TIME)), DATETIME) AS 'formattedDate' FROM dbs.tableName;
drop table test
create table test(
CollectionDate date NULL,
CollectionTime [time](0) NULL,
CollectionDateTime as (isnull(convert(datetime,CollectionDate)+convert(datetime,CollectionTime),CollectionDate))
-- if CollectionDate is datetime no need to convert it above
)
insert test (CollectionDate, CollectionTime)
values ('2013-12-10', '22:51:19.227'),
('2013-12-10', null),
(null, '22:51:19.227')
select * from test
CollectionDate CollectionTime CollectionDateTime
2013-12-10 22:51:19 2013-12-10 22:51:19.000
2013-12-10 NULL 2013-12-10 00:00:00.000
NULL 22:51:19 NULL
This works in SQL 2008 and 2012 to produce datetime2:
declare #date date = current_timestamp;
declare #time time = current_timestamp;
select
#date as date
,#time as time
,cast(#date as datetime) + cast(#time as datetime) as datetime
,cast(#time as datetime2) as timeAsDateTime2
,dateadd(dayofyear,datepart(dayofyear,#date) - 1,dateadd(year,datepart(year,#date) - 1900,cast(#time as datetime2))) as datetime2;
dealing with dates, dateadd must be used for precision
declare #a DATE = getdate()
declare #b time(7) = getdate()
select #b, #A, GETDATE(), DATEADD(day, DATEDIFF(day, 0, #a), cast(#b as datetime2(0)))
I am using SQL Server 2016 and both myDate and myTime fields are strings. The below tsql statement worked in concatenating them into datetime
select cast((myDate + ' ' + myTime) as datetime) from myTable
SELECT CONVERT(DATETIME, CONVERT(CHAR(8), date, 112) + ' ' + CONVERT(CHAR(8), time, 108))
FROM tablename

How to Insert varchar data into a datetime field (SQL Server 2005)?

I have this data I want inserted to a table. Sample data MM/DD/YYYY + 1 day and 12:00:00 PM
Basically what I need is to insert the current date + 1 day and specific time of 12:00:00 PM.
My code is this:
DECLARE #MyEstimatedDate as varchar(100) ---TEMPORARY CONTAINER
DECLARE #MyEstimatedDate1 as varchar(100) ---TEMPORARY CONTAINER
DECLARE #MyEstimatedDate2 as varchar(100) ---TEMPORARY CONTAINER
DECLARE #MyEstimatedDate3 as DATETIME ---FINAL DATA NEEDED. This is the data I want inserted.
SET #MyEstimatedDate = DATEADD(day,1,GETDATE())
SET #MyEstimatedDate1 = CONVERT(VARCHAR(100),#MyEstimatedDate,101)
SET #MyEstimatedDate2 = #MyEstimatedDate1 + ' 12:00:00 PM'
SET #MyEstimatedDate3 = cast(#MyEstimatedDate2 as datetime) ---I believe this is the error
Error message I get:
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
Just don't use varchar when manipulating datetime data. SQL Server 2005 offers enough tools for you to be able to avoid conversion.
The following is a more or less known method of dropping the time part from a datetime value:
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, #InputDateTime), 0);
In the above example, DATEDIFF calculates the number of days between a date specified as 0 and the given date. The number of days is then added by the DATEADD function to the 0 date. The final result is a datetime value with the time of 00:00:00 and the same date as #InputDateTime. This is because the 0 date is an integer representation of 1900-01-01 00:00:00: its time part is zero and, since we have incremented it by a whole number of days, so is the result's time part.
Now, if instead of the DATEDIFF days you add DATEDIFF+1, you will get the next day. Furthermore, if instead of 0 as the date to be incremented you use 12:00, you will get the next day's noon, which appears to be what you want. So, the final expression will look like this:
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, #InputDateTime) + 1, '12:00');
Since your input timestamp is supposed to be the current date & time, just replace #InputDateTime with GETDATE():
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) + 1, '12:00');
Why not simply do
cast(dateadd(day, 1, getdate()) as date)
that was for midnight. For noon, do this
dateadd(hour, 12, cast(cast(dateadd(day, 1, getdate()) as date) as datetime))
forget the above, it's wrong.
Correct answer is
dateadd(hour, 12, cast(cast(dateadd(day, 1, getdate()) as date) as datetime))
This time I even tested it.
datetime type contains date + time. In your case for #MyEstimatedDate1 need just a date
DECLARE #MyEstimatedDate varchar(100) ---TEMPORARY CONTAINER
DECLARE #MyEstimatedDate1 varchar(100) ---TEMPORARY CONTAINER
DECLARE #MyEstimatedDate2 varchar(100) ---TEMPORARY CONTAINER
DECLARE #MyEstimatedDate3 DATETIME ---FINAL DATA NEEDED. This is the data I want inserted.
SET #MyEstimatedDate = DATEADD(day, 1, GETDATE())
SET #MyEstimatedDate1 = CONVERT(VARCHAR(100), CAST(#MyEstimatedDate AS date), 101)
SET #MyEstimatedDate2 = #MyEstimatedDate1 + ' 12:00:00 PM'
SET #MyEstimatedDate3 = cast(#MyEstimatedDate2 as datetime) ---I believ
OR simple to use it
SELECT DATEADD(hour, 36, GETDATE() - CAST(GETDATE() AS time))

Extract time from datetime efficiently (as decimal or datetime)

I have been able to find a lot of information for getting a string representation of just the time from a datetime column like this one.
I need to get the time part out of a datetime in a way that I can do some math on it like adding it to another datetime. So a string representation of the time wont help me.
However I've only found one example that will extract the time as a numeric type value. I.e:
SELECT CAST(GETDATE() AS FLOAT) - FLOOR(CAST(GETDATE() AS FLOAT))
This method requires two casts though and I have to run this on over 10,000 rows. Is there anything similar to the dateadd method for extracting the date part from a datetime column i.e.:
select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
that I can use to get just the time out of a datetime column and return it as a decimal or datetime? Perhaps a solution that uses less casting?
I am using SQL Server 2000.
To get a datetime:
SELECT GetDate() - DateDiff(day, 0, GetDate());
-- returns the time with zero as the datetime part (1900-01-01).
And to get a number representing the time:
SELECT DateDiff(millisecond, DateDiff(day, 0, GetDate()), GetDate());
-- time since midnight in milliseconds, use as you wish
If you really want a string, then:
SELECT Convert(varchar(8), GetDate(), 108); -- 'hh:mm:ss'
SELECT Convert(varchar(12), GetDate(), 114); -- 'hh:mm:ss.nnn' where nnn is milliseconds
One way You can get the time in seconds is with:
select cast(datediff(second, DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0), getdate())/(60*60*24.0) as datetime)
This calculates the time in seconds and then converts back to a datetime.
To get it as a decimal:
select datediff(second, DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0), getdate())/(60*60*24.0)
Or use "ms" if you prefer millisecond precision.
Or, you can use the more readable:
select datepart(hh, getdate())/24.0+datepart(mm, getdate())/(24*60.0)+
datepart(ss, getdate())/(24*60*60.0)

A way to extract from a DateTime value data without seconds

I have an sql DateTime (ms sql server) and want to extract the same date without the seconds:
e.g. 2011-11-22 12:14:58.000 to become: 2011-11-22 12:14:00.000
How can I do this? I was thinking to use DATEADD in combination with DATEPART but seems very error prone (besides performance issues)
SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, yourcolumn), 0) FROM yourtable
This will be effective, if you don't want a slow conversion between datatypes.
For a solution that truncates using strings try this:
SELECT CAST(CONVERT(CHAR(16), GetDate(),20) AS datetime)
CHAR(16) works only if our variable is converted to ODBC canonical format, as shown above by using 20 as the format specifier.
DECLARE #date DateTime = '2011 Nov 22 12:14:55';
SELECT CONVERT(Char(16), #date ,20) AS datetime
Results:
| datetime |
|------------------|
| 2011-11-22 12:14 |
Then you simply cast back to a DateTime type to continue using the value.
NOTE: This is only viable for data types that do not carry TimeZone info.
Also type conversions to VarChar and back are usually LESS performant than using DateTime functions that use numeric operations internally.
Consider other solutions posted if performance is a concern or if you must retain timezone information.
DECLARE #TheDate DATETIME
SET #TheDate = '2011-11-22 12:14:58.000'
DATEADD(mi, DATEDIFF(mi, 0, #TheDate), 0)
In queries
/* ...all records in that minute; index-friendly expression */
WHERE TheDate BETWEEN DATEADD(mi, DATEDIFF(mi, 0, #TheDate), 0)
AND DATEADD(mi, DATEDIFF(mi, 0, #TheDate) + 1, 0)
Date and time needs carefully and not being converted as TEXT.
My personal solution:
CREATE FUNCTION [dbo].[fnDateTimeTruncated]
(
#datetime DATETIME
)
RETURNS DATETIME
AS
BEGIN
RETURN DATETIMEFROMPARTS ( year(#datetime), month(#datetime), day(#datetime), DATEPART(hh,#datetime), DATEPART(mi,#datetime), 0, 0)
END
Edited:
Regarding http://blog.waynesheffield.com/wayne/archive/2012/03/truncate-a-date-time-to-different-part/, DateAdd has a better performance.
Thanks to t-clausen.dk
With a little fiddling around, this seems to work well:
SELECT CAST(CONVERT(CHAR(17), bl.[time],113) AS varchar(17))
Result given: 2011-11-22 12:14
The exact way I'm using it in my query as part of the selection list :
,CAST(CONVERT(CHAR(17), bl.[time],113) AS varchar(17))
+ ' (UTC +0)' AS [TIME]
Gives me the result: 15 Dec 2017 06:43 (UTC +0)
From SQL Server 2014, You can use Format function for this.
for Ex.
declare #Startdate datetime = '2020-11-07 15:27:50.713'
set #Startdate = Convert(datetime,FORMAT(#Startdate, 'yyyy-MM-dd HH:mm'))
> Result is
2020-11-07 15:27:00.000
If there is no milliseconds, than
DECLARE #dt datetime2 = '2011-11-22 12:14:58.000';
DECLARE #goalDt datetime2 = DATEADD(second,-DATEPART(second,#dt), #dt);
To remove a milliseconds part, add
SET #goalDt = DATEADD(millisecond,-DATEPART(millisecond,#goalDt ), goalDt dt);
To Round Off it:
DECLARE #TheDate DATETIME;
SET #TheDate = '2019-1-2 12:14:58.400';
SELECT CAST(#TheDate AS SMALLDATETIME);
To just Truncate:
DECLARE #TruncTheDate DATETIME;
SET #TruncTheDate = '2019-1-2 12:14:58.400';
SELECT DATEADD(mi, DATEDIFF(mi, 0, #TruncTheDate), 0);
select substring(cast(cast(getdate() as time(0)) as char(8)),0,6)