Why does my query return records which doesn't meet the where clause conditions? - sql

I have written a query which returns records with dates that are actually older than the mentioned date.
Declare #DateFrom date
Set #DateFrom= '02/Oct/2019'
SELECT 1, Convert(varchar(11), AppliedDateTime, 106)
FROM [MC_Tenders].[dbo].[AppliedWorks]
Where
Convert(varchar, AppliedDateTime,106) >= Convert(varchar, #DateFrom,106)
Applied dates are saved in table as datetime e.g. 2017-04-25 15:51:25.257

You are doing the comparison as strings rather than dates. Remove the conversion:
SELECT 1, Convert(varchar(11), AppliedDateTime, 106)
FROM [MC_Tenders].[dbo].[AppliedWorks]
WHERE AppliedDateTime >= #DateFrom;
Type 106 is dd mm yyyy. When you compare as strings, the strings are compared, not the dates. With format 106, the days are compared first, so: '18-10-2017' < '25-12-1900' because "1" < "2".

Just to finish Gordon Linoff's thought, your code should look something like this:
SELECT
1
, CAST(AppliedDateTime AS DATE) AS AppliedDate
FROM
[MC_Tenders].[dbo].[AppliedWorks]
WHERE
CAST(AppliedDateTime AS DATE) >= #DateFrom;
Edit: I'm assuming AppliedDateTime is actually stored as a datetime, or some data type other than DATE. The explicit CAST to the DATE type will strip out the time component and allow SQL to just compare the date component to your variable.

Related

How to subtract one month from a date using SQL Server

I have a date in format dd/mm/yyyy. I want to subtract one month from it.
I am using this code but the output is "09/10/2020" I don't know why my code does the subtraction of the year -2 also.
This is my request
SELECT
FORMAT(CONVERT (DATE, DATEADD(MONTH, -1, CONVERT(char(9), GETDATE()))), 'dd/MM/yyyy')
you need to change it to:
select format(CONVERT (date,DATEADD(MONTH, -1,GETDATE())), 'dd/MM/yyyy' )
but as Larnu stated. it seems like you need to change the column.
Your current code doesn't work as expected because:
SELECT CONVERT(char(9), GETDATE());
Returns this (at least in my language):
Nov 9 20
Which is, unfortunately, and again in my language, a valid date (but in {20}20, not {20}22).
Even in the right style (103), char(9) would yield 10/11/202 tomorrow, since 9 digits is only enough if either the day or month is a single digit.
Don't know why you are converting GETDATE() to a string. Just perform date math on it and then format it if you need to (using a specific style number, e.g. 103 for d/m/y):
SELECT CONVERT(char(10), DATEADD(MONTH, -1, GETDATE()), 103);
I really wouldn't use FORMAT() for such simple output, as the CLR overhead really isn't worth it. Ideally you leave it as a date/time type until presentation time - surely your presentation layer can present your date as d/m/y if that's really a wise idea.
And if you are storing or passing dates as strings (and worse, in regional formats like d/m/y) you really should consider fixing that.
First of all,
You should be storing your Date as a string for easier manipulation. If you don't want to change the column, you can always convert from Date to Varchar and then (re)convert it.
Example:
First, convert Date to varchar using the style code '112' ISO for formatting as yyyyMMdd:
DECLARE #date DATE = GETDATE();
DECLARE #dateConverted as VARCHAR (8) = (SELECT CONVERT(VARCHAR, #date, 112));
Then you just subtract the month using DATEADD():
DECLARE #previousMonth AS VARCHAR (8) = (SELECT FORMAT(DATEADD(month, -1, #dateConverted), 'yyyyMMdd'));
Finally, convert varchar do Date again:
DECLARE #previousMonthConverted AS DATE = (SELECT CONVERT(CHAR(10), CONVERT(date, #previousMonth), 120));

incorrect results while passing a datetime instead of getdate()

I am working on a SQL query which returns all records between two dates from a table as follows
select convert(varchar(2),TestDate,108) from dbo.Table
where TestDate between convert(datetime,convert(varchar,GETDATE(),101))
and dateadd(day,1,convert(datetime,convert(varchar,GETDATE(),101)))
The above query works fine and gives me the desired results but when I tried to use a normal date string instead of getdate(), the query returns and empty result as follows
select convert(varchar(2),TestDate,108) from dbo.Table
where TestDate between convert(datetime,convert(varchar,'2015-12-27 00:00:00.000',101)) and dateadd(day,1,convert(datetime,convert(varchar,2015-12-27 00:00:00.000',101)))
The above query returns an empty result set which is not what I wanted.
I tried passing date string in different formats but that didn't work.
May I know a correct way to do it?
Why would you convert dates to a string for comparisons? Just do the comparisons as dates.
In addition, you can use datepart() to extract the hour, rather than using some esoteric format to convert():
select datepart(hour, TestDate)
from dbo.Table
where TestDate between cast(GETDATE() as date) and
cast(dateadd(day, 1, getdate()) as date)
If you want the hour as a string instead of a number, then use datename() rather than datepart().
I guess that you are having an extra CONVERT.
Wherever you have this
convert(varchar,GETDATE(),101)
just replace with your date:
'2015-12-27 00:00:00.000'
because the purpose of the CONVERT function is to translate a Date into a Varchar
In addition to Gordon's answer, you can substitute string dates as so:
select datepart(hour, TestDate)
from dbo.Table
where TestDate between cast('2015-12-27 00:00:00.000' as date) and
cast(dateadd(day, 1, '2015-12-27 00:00:00.000') as date)
Assuming this is for a webapp, be sure to use placeholders instead of actual text to prevent SQL insertion attacks.

How to filter only the date from a string stored in a varchar

Ii have values stored in the SQL Server in the following manner : 02-Jul-12 12:00:00 AM here the time and minutes, seconds can be anything like 02-Jul-12 12:15:52 PM ,02-Jul-12 6:02:12 AM so on.
I want to have a where condition which will omit the time and take the data based on the date like the following where some_Date='02-Jul-12'
How would I do this?
SELECT * FROM whatever WHERE some_Date LIKE '02-Jul-12%';
If you are on SQL2008 or later, you can cast your DATETIME to DATE.
See this post: http://blog.sqlauthority.com/2012/09/12/sql-server-get-date-and-time-from-current-datetime-sql-in-sixty-seconds-025-video/
But in a WHERE-clause it is better to search between dates, like this:
DECLARE #startDate DATETIME = '02-Jul-2012'
DECLARE #endDate DATETIME = DATEADD(DAY, 1, #startDate)
SELECT * FROM [table] WHERE [some_Date] BETWEEN #startDate AND #endDate
SELECT * FROM dbo.tbl_MyTable
WHERE
REPLACE(CONVERT(VARCHAR(9), DateTimeValueColumn, 6), ' ', '-')='02-Jul-12'
or
On chage in code is instead of using getdate function voncert you datestring in datetime format and do compare this follow query will work for you
SELECT * FROM dbo.tbl_MyTable
WHERE
CAST(CONVERT(CHAR(10), DateTimeValueColumn, 102) AS DATE) =
CAST(CONVERT(CHAR(10),GETDATE(),102) AS DATE)
If you are storing dates as characters -- which is not recommended -- you should at least use ISO format: YYYY-MM-DD hh:mm:ss. This makes the date useful for sorting and comparisons ("<" works, ">" works, "between" works as well as equals).
To extract the date, you can then use left(datestr, 10). In your format, you would use:
where left(datestr, 9) = '01-Jan-13'
If you are storing the fields as a datetime or smalldatetime, you may think they are stored as a string. They are not. They are stored as some number of days since some particular date, with day parts stored as fractional days. If you are using SQL Server 2005 or greater, then the best way is:
where cast(datetime as date) = '2013-01-01' -- I recommend ISO formats, even for constants. '20130101' is even better
To select rows with today's date (not time)
select * from myTable where datediff(dd, dateColumn, getdate()) = 0

Microsoft SQL Server 2008 - Dates

I have a couple of questions in regards to dates in SQL Server.
How do I separate a datetime value "2011-08-10 14:56:17.267" into date and timestamp in two separate columns. Eg. Date "2011-08-10" and timestamp "14:56:17"
I want remove the timestamp from datetime value into "2011-08-10" and still be able to order the data by date (therefore not converted to varchar). Also is there away to change the date value as '10 Aug 2011' and still can sort (not alphabetically but in real date order).
Thank you,
HL
For the first one:
UPDATE atable
SET
DateColumn = CAST(DateTimeColumn AS date),
TimeColumn = CAST(DateTimeColumn AS time)
As for the second one, date display format is something that is unrelated to the date value. You can order the result set by your date column, but in the SELECT clause you can use CONVERT to display the date in the desired format. For example:
SELECT
CONVERT(varchar, DateColumn, 106) AS Date,
…
FROM atable
ORDER BY DateColumn
use CONVERT function with parameters from resource http://www.mssqltips.com/tip.asp?tip=1145
-- simple conversion example:
SELECT CONVERT(VARCHAR(10), GETDATE(), 102) -- for date
SELECT CONVERT(VARCHAR(10), GETDATE(), 8) -- for time

Compare DATETIME and DATE ignoring time portion

I have two tables where column [date] is type of DATETIME2(0).
I have to compare two records only by theirs Date parts (day+month+year), discarding Time parts (hours+minutes+seconds).
How can I do that?
Use the CAST to the new DATE data type in SQL Server 2008 to compare just the date portion:
IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)
A small drawback in Marc's answer is that both datefields have been typecast, meaning you'll be unable to leverage any indexes.
So, if there is a need to write a query that can benefit from an index on a date field, then the following (rather convoluted) approach is necessary.
The indexed datefield (call it DF1) must be untouched by any kind of function.
So you have to compare DF1 to the full range of datetime values for the day of DF2.
That is from the date-part of DF2, to the date-part of the day after DF2.
I.e. (DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
NOTE: It is very important that the comparison is >= (equality allowed) to the date of DF2, and (strictly) < the day after DF2. Also the BETWEEN operator doesn't work because it permits equality on both sides.
PS: Another means of extracting the date only (in older versions of SQL Server) is to use a trick of how the date is represented internally.
Cast the date as a float.
Truncate the fractional part
Cast the value back to a datetime
I.e. CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)
Though I upvoted the answer marked as correct. I wanted to touch on a few things for anyone stumbling upon this.
In general, if you're filtering specifically on Date values alone. Microsoft recommends using the language neutral format of ymd or y-m-d.
Note that the form '2007-02-12' is considered language-neutral only
for the data types DATE, DATETIME2, and DATETIMEOFFSET.
To do a date comparison using the aforementioned approach is simple. Consider the following, contrived example.
--112 is ISO format 'YYYYMMDD'
declare #filterDate char(8) = CONVERT(char(8), GETDATE(), 112)
select
*
from
Sales.Orders
where
CONVERT(char(8), OrderDate, 112) = #filterDate
In a perfect world, performing any manipulation to the filtered column should be avoided because this can prevent SQL Server from using indexes efficiently. That said, if the data you're storing is only ever concerned with the date and not time, consider storing as DATETIME with midnight as the time. Because:
When SQL Server converts the literal to the filtered column’s type, it
assumes midnight when a time part isn’t indicated. If you want such a
filter to return all rows from the specified date, you need to ensure
that you store all values with midnight as the time.
Thus, assuming you are only concerned with date, and store your data as such. The above query can be simplified to:
--112 is ISO format 'YYYYMMDD'
declare #filterDate char(8) = CONVERT(char(8), GETDATE(), 112)
select
*
from
Sales.Orders
where
OrderDate = #filterDate
You can try this one
CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000')
I test that for MS SQL 2014 by following code
select case when CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000') then 'ok'
else '' end
You may use DateDiff and compare by day.
DateDiff(dd,#date1,#date2) > 0
It means #date2 > #date1
For example :
select DateDiff(dd, '01/01/2021 10:20:00', '02/01/2021 10:20:00')
has the result : 1
For Compare two date like MM/DD/YYYY to MM/DD/YYYY .
Remember First thing column type of Field must be dateTime.
Example : columnName : payment_date dataType : DateTime .
after that you can easily compare it.
Query is :
select * from demo_date where date >= '3/1/2015' and date <= '3/31/2015'.
It very simple ......
It tested it.....