This seems like overkill but is the only way I have been able to floor todays datetime to 00:00:00.000 at database level:
select CAST(FLOOR(CAST(CURRENT_TIMESTAMP AS float)) AS DATETIME)
I have tried using:
select FLOOR(getdate())
But get the following message:
Implicit conversion from data type datetime to float is not allowed. Use the CONVERT function to run this query.
Can anyone recommend another way of doing this?
Since you are using SQL Server 2008 you could make use of the date data type.
declare #Today date
set #Today = getdate()
select #Today
Or without the variable.
select cast(getdate() as date)
If you need to have the value as a datetime just cast it back to a datetime.
select cast(cast(getdate() as date) as datetime)
There are a lot of ways of doing this i have seen the floor one before. Here are a few more.
select cast(cast(CURRENT_TIMESTAMP as date) as datetime)
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP), 0)
SELECT CAST(CAST(CURRENT_TIMESTAMP - 0.50000004 AS int) AS datetime)
I normaly do the Cast to date version.
Related
I was going through some queries and found some where clauses the following way
convert(varchar, datefield, 101) between convert(varchar, #startdate, 101) and convert(varchar, #enddate, 101)
My question is this the right approach to check a datetime value between date ranges? Will this approach fetch me the wrong value? If so, please provide some explanations.
Don't convert your Date to a varchar and compare because string comparisson is not fast. It is much faster if you use >= and < to filter your date column.
DO NOT use the following, as it could return some records from #enddate if their times are 00:00:00.000.
datefield between #startdate and #enddate
Fastest way to convert datetime to date.
On SQL Server 2008 and higher, you should convert to date:
SELECT CONVERT(date, getdate())
No varchar<->datetime conversions required
No need to think about locale
I have a sql 2008 database and I am creating a stored procedure that shall check if a datetime is more than 3 hours old but I don't know how to do it.
Do you have some way to do it?
the datetime is a field in the table.
BR
Rather than applying DATEDIFF to the column value, which will negate an index, I suggest using a comparison of the column to an expression (which can use an index).
If you want this as a filter:
SELECT columns
FROM dbo.table
WHERE DateTimeColumn < DATEADD(HOUR, -3, CURRENT_TIMESTAMP);
(If you want only the rows that are newer than 3 hours old, change < to > or >=.)
If you want to return all rows with a column showing whether it is more than 3 hours old:
SELECT columns, [3HoursOld] = CASE
WHEN DateTimeColumn < DATEADD(HOUR, -3, CURRENT_TIMESTAMP)
THEN 'Yes, older than 3 hours.'
ELSE 'No, not older than 3 hours.'
END
FROM dbo.table;
Take at look at the DATEDIFF function.
DATEDIFF ( datepart , startdate , enddate )
You would then use with datepart set to hh and the enddate set to the current time. To get the current database time you could use GETDATE(). Compare the result with 3 since it will return the number of hours passed.
#date is the date you want to compare
declare #date datetime
set #date= '2012-02-15 14:20:42.797'
SELECT DateDiff(hh, DATEADD(hh,-3,#date), GETDATE()) --if it's > 3
you better create a Boolean function that does the trick that you can use where ever you like
I have used a convert function in one of my Queries
Select * from tblMas where FromDate >= CONVERT(varchar(10), #FromDate,112)
#FromDate is a Datetime parameter, I don't know why but this query works fine.
Though it should not as FromDate is of DateTime field and we are comparing it with Varchar field.
CONVERT(varchar(10), #FromDate, 112) returns result in yyyyMMdd format. I am lost how SQL Server is comparing this and returning right result.
There will be an implicit type conversion from varchar to datetime before the comparison.
If you have a look at the queryplan you will see something like this.
<ScalarOperator ScalarString="[FromDate]>=CONVERT_IMPLICIT(datetime,CONVERT(varchar(10),[#FromDate],112),0)">
Another way to remove the time part from a datetime.
select *
from tblMas
where FromDate >= dateadd(day, datediff(day, 0, #FromDate), 0)
In SQL Server 2008 you can use
select *
from tblMas
where FromDate >= cast(#FromDate as date)
I need help with query to find all the dates that between 31/12/2009 and 31/02/2010
In SQL Server 2008
i try this:
SELECT convert(varchar(50), MyDate, 103)
where convert(varchar(50), MyDate, 103) >= '31/12/2009' and convert(varchar(50), MyDate, 103) <='31/02/2010'
but it give me wrong result
why ?
I had a different interpretation of the question: "how to generate all the dates between a certain range?"
Here's a solution to that:
--define start and end limits
Declare #todate datetime, #fromdate datetime
Select #fromdate='2009-03-01', #todate='2009-04-10'
;With DateSequence( Date ) as
(
Select #fromdate as Date
union all
Select dateadd(day, 1, Date)
from DateSequence
where Date < #todate
)
--select result
Select * from DateSequence option (MaxRecursion 1000)
There is a nice article that shows how to generate sequences (numbers, dates, times) using CTEs.
Edit:
After clarification, the issue seems to be the date format being input: dd/mm/yyyy.
SQL Server expects the format mm/dd/yyyy.
I would simply transform it before running the select statement:
-- Assuming two variables, #inputFromDate and #inputToDate, in the format of dd/mm/yyyy...
declare #fromDate varchar(10), #toDate varchar(10)
set #fromDate =
substring(#inputFromDate, 3, 2) + '/' +
substring(#inputFromDate, 1, 2) + '/' +
substring(#inputFromDate, 7, 4)
set #toDate =
substring(#inputToDate, 3, 2) + '/' +
substring(#inputToDate, 1, 2) + '/' +
substring(#inputToDate, 7, 4)
select * from SomeTable where dateCol >= #fromDate and dateCol < #toDate
-- you can change the < or >= comparisons according to your needs
If the MyDate column is a datetime, as it appears to be, then it's already in the right "format". Don't convert it to a varchar(50) in the predicate condition - this makes your query non-sargable and will kill performance on any indexes you might have.
Instead, take your parameters as date or datetime instances:
SELECT ...
FROM MyTable
WHERE MyDate >= #BeginDate
AND MyDate <= #EndDate
Your query should not depend on a specific date format in the input parameters - those parameters are not varchar types, they are datetime (or date). When you run this query or stored procedure from whatever environment the application is in and supply binding parameters (you are using bind parameters, right?), said library will automatically handle any formatting issues.
If you try to use the >= and <= operators on character representations of dates, with any format other than the ISO standard yyyymmdd, you will get the wrong results, because the alphabetical order is different from the temporal order. Don't do this.
If you simply need to write an ad-hoc query, i.e. this isn't being run from any programming environment, then simply do not use the dd/mm/yyyy format. Use the ISO date format instead; it is unambiguous and implicitly convertible to datetime values:
SELECT ...
FROM MyTable
WHERE MyDate >= '20091231'
AND MyDate <= '20100231'
Honestly, no other solution is acceptable in my mind. For ad-hoc queries, always use the unambiguous ISO standard for dates. For applications connecting to the database, always use bind parameters. If you're doing anything else, you're writing code that's either unreliable, insecure, or both.
BOL is always a good reference...
Start with BETWEEN
Did you try this:
DECLARE #FROMDATE DATETIME
DECLARE #TODATE DATETIME
SET #FROMDATE = GETDATE()
SET #TODATE = GETDATE()+7
;WITH DATEINFO(DATES) AS (SELECT #FROMDATE UNION ALL SELECT DATES + 1 FROM DATEINFO WHERE DATES < #TODATE)
SELECT * FROM DATEINFO OPTION (MAXRECURSION 0)
I need to search between dates and times.
For example, between date: 30/02/2007, time: 10:32 and date: 21/06/2008, time: 14:19
What is the most simple query for this?
Thanks in advance.
you should look at the date time formats available in SQL Server: http://msdn.microsoft.com/en-us/library/ms187928.aspx
yyyy-mm-dd hh:mi is what you should use:
try:
SELECT
*
FROM Records
WHERE DateCreated>='2007-02-30 10:32' AND DateCreated<='2008-06-21 14:19'
in the above query the strings will be converted to datetime data type if DateCreated is a datetime column. and the query will work.
you can create local variables of datetime data type and use a query like:
DECLARE #StartDate datetime, #EndDate datetime
SELECT #StartDate='2007-02-30 10:32', #EndDate='2008-06-21 14:19'
SELECT
*
FROM Records
WHERE DateCreated>=#StartDate AND DateCreated<=#EndDate
I like using <, <=, >=, or > because it allows more flexibility than BETWEEN and forces you to think about including endpoints or not.
Another thing to consider is getting all data from a complete day:
DECLARE #StartDate datetime, #EndDate datetime
--set the days you want
SELECT #StartDate='2007-02-30 10:32', #EndDate='2008-06-21 14:19'
--remove the time
SELECT #StartDate=DATEADD(day,DATEDIFF(day,0,#StartDate),0), #EndDate=DATEADD(day,DATEDIFF(day,0,#EndDate),0)
--get everything on '2007-02-30' up to the end of the day on '2008-06-21'
SELECT
*
FROM Records
WHERE DateCreated>=#StartDate AND DateCreated<#EndDate+1
Try this:
SELECT
*
FROM
Records
WHERE
DateCreated BETWEEN #Date1 AND #Date2