Need to calculate date difference of today date vs converted date field - sql

I have a table with a column that was previously converted using
(CONVERT(VARCHAR(19), GETDATE(), 112)
With the getdate being the date when the field was inserted. Now I have to compare the current date against the date the field was inserted.
The issue I'm facing is that when the date field is from last month, say 20131004, I calculate date difference by (CONVERT(VARCHAR(19), GETDATE(), 112) - 20131004, the result is 200. Obviously this is wrong...
Could you please suggest me how I could calculate the true date difference?

You should be using the DATE or DATETIME data type for that column. Why on earth would you ever store a date as a string? Do you know how much you lose by doing so? Validation, for one - a VARCHAR(19) column will accept 20131004 12:34 PM but will also accept nonsense values like I am not a date!.
If the data is actually good, you can simply do this instead of lazy shorthand and without any explicit conversions:
SELECT DATEDIFF(DAY, column_name, GETDATE()) FROM dbo.table;
If you get an error message with this, then you have bad data. You can identify it like this:
SELECT column_name FROM dbo.table WHERE ISDATE(column_name) = 0;
Please read:
Bad habits to kick : choosing the wrong data type
Bad habits to kick : mis-handling date / range queries
Bad Habits to Kick : Using shorthand with date/time operations

I agree with #Aaron that you should store a date field in a date field, not a text field.
If for some reason you do want to store it in a text field then the easiest way to calculate the number of days is to convert it back to a date field and then compare it:
SELECT DATEDIFF(DAY, CAST(column_name as DATETIME), GETDATE()) FROM dbo.table
This will throw an error if the value in the column cannot be converted to a date. You'll also need to make sure that the date is formatted correctly for your database. Assuming you use the format 112 you should be ok, but if you have the value 04/12/2013 in the column is that the 4th December 2013 or the 12th April 2013? It depends on how your database is configured.
But anyway, if you always insert dates in that field then you're nuts not making it a date field.
If you need to display the date somewhere then convert it on the way out.

Related

How to use between clause for getting data between two dates?

I have date field in the database in the format 2012-03-17 19:50:08.023.
I want to create a select query which gives me the data collected in the March month.
But I am not able to achieve this.
I am trying following query.
select * from OrderHeader where
Convert(varchar,UploadDt,103) between '01/03/2013' and '31/03/2013'
and DistUserUniqueID like '6361%'
This query gives me data for all the dates.
select * from OrderHeader where
UploadDt between '01/03/2013' and '31/03/2013' and DistUserUniqueID like '6361%'
This query gives me the error as Msg 242, Level 16, State 3, Line 1
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Please help me resolve this.
Thanks in advance
The first query returns all dates because you are converting your column to a string. Not sure why you are doing this. So when you say BETWEEN '01/anything' AND '31/anything', when you consider it is now just a string, that is going to match all "dates" in the column, regardless of month and year, since your WHERE clause will cover every single day possible (well, with the exception of the 31st of months other than March, and the first day in January and February - so not all the data but a very large percentage). '15/11/2026', for example, is BETWEEN '01\03\2013' AND '31/03/2013'.
Think about that for a second. You have datetime data in your database, and you want to convert it to a string before you query it. Would you also convert salary to a string before comparing it? If so, the person making $70,000 will look like they are making more than the person making $690,000, since character-based sorting starts at the first character and doesn't consider length.
The second query fails because you are using a regional, ambiguous format for your dates. You may like dd/mm/yyyy but clearly your server is based on US English formatting where mm/dd/yyyy is expected.
The solution is to use a proper, unambiguous format, such as YYYYMMDD.
BETWEEN '20130301' AND '20130313'
However you shouldn't use BETWEEN - since this is a DATETIME column you should be using:
WHERE UploadDt >= '20130301'
AND UploadDt < '20130401'
(Otherwise you will miss any data from 2013-03-31 00:00:00.001 through 2013-03-31 23:59:59.997.)
If you really like BETWEEN then on 2008+ (you didn't tell us your version) you can use:
WHERE CONVERT(DATE, UploadDt) BETWEEN '20130301' AND '20130331'
More date-related tips here:
Dating Responsibly
Finally, when converting to VARCHAR (or any variable-length data types), always specify a length.
Rewrite the query as
select * from OrderHeader where
UploadDt between '01/03/2013' and '01/04/2013'
and DistUserUniqueID like '6361%'
or
select * from OrderHeader where
UploadDt between Convert(datetime,'01/03/2013', 103) and Convert(datetime,'01/04/2013',103)
and DistUserUniqueID like '6361%'

Insert only Month and Year date to SQL table

I am using MS SQLServer and trying to insert a month/year combination to a table like this:
INSERT INTO MyTable VALUES (1111, 'item_name', '9/1998')
apparently, the above command cannot work since
Conversion failed when converting date and/or time from character string.
Because 9/1998 is a bad format. I want to fix this and this column of the table will show something like:
9/1998
12/1998
(other records with month/year format)
...
Can someone help me with this?
thank you
SQL Server only supports full dates (day, month, and year) or datetimes, as you can see over on the MSDN data type list: http://msdn.microsoft.com/en-us/library/ff848733(v=sql.105).aspx
You can use a date value with a bogus day or store the value as a string, but there's no native type that just stores month/year pairs.
I see this is an old post but my recent tests confirm that storing Date or splitting the year and month to two columns (year smallint, month tinyint) results in the overall same size.
The difference will be visible when you actually need to parse the date to the filter you need (year/month).
Let me know what do you think of this solution! :)
Kind regards
You can just use "01" for the day:
INSERT INTO MyTable VALUES (1111, 'item_name', '19980901')
You can:
1) Change the column type to varchar
2) Take the supplied value and convert it to a proper format that sql server will accept before inserting, and format it back to 'M/YYYY' format when you pull the data: SELECT MONTH([myDate]) + '/' + YEAR([myDate]) ...
You may want to consider what use you will have for your data. At the moment, you're only concerned with capturing and displaying the data. However, going forward, you may need to perform date calculations on it (ie, compare the difference between two records). Because of this and also since you're about two-thirds of the way there, you might as well convert this field to a Date type. Your presentation layer can then be delegated with the task of displaying it appropriately as "MM/yyyy", a function which is available to just about any programming language or reporting platform you may be using.
if you want use date type, you should format value:
declare #a date
SELECT #a='2000-01-01'
select RIGHT( convert (varchar , #a, 103), 7) AS 'mm/yyyy'
if you want make query like SELECT * FROM...
you should use varchar instead date type.

SQL: Counting dates formatted as varchar

The task:
I need to count every record in a table that was added after 07/01/2011.
Info:
There is a column in the table "Date_added" which is formatted as varchar and contains dates in format mm/dd/yyyy.
What I've tried:
I tried the following query:
SELECT count(date_added) FROM Abatements_Doc WHERE date_added >= '07/01/2011'
Unfortunately it counted any date where the month was greater than 07 regardless of the year or day. I'm at a loss as to how I should format my query to get it to read the dates properly instead of by ascii sort. In my research I discovered the CAST and CONVERT options, but am not sure how to use them, or which one I should use if any. I'm extremely new to SQL, and want to make sure I don't mess up the data in the table. I just need to get the count as specified above without altering the data in the table in any way. Any help in this regard will be very much appreciated. Thanks in advance.
I didn't test. But try convert statement.
SELECT count(date_added)
FROM Abatements_Doc
WHERE convert(datetime,date_added,1) >= convert(datetime,'07/01/2011',1)
(1) don't use mm/dd/yyyy as your date format. Use a safe and unambiguous format; the only one I trust for DATETIME/SMALLDATETIME is YYYYMMDD.
(2) change the data type in your table to DATETIME/SMALLDATETIME/DATE depending on accuracy required. Then `WHERE date_added >= '20110701' will work just fine (and will use an index on that column, if one exists).
(3) if you can't change the data type, then the following will work just fine as well (though no index will be used):
WHERE CONVERT(DATETIME, date_added, 101) >= '20110701'
Varchar can't be compared, try changing your column to date type.
Convert both date_added column values and your target date to DATETIME and compare; as in:
SELECT COUNT(1)
FROM Abatements_Doc
WHERE (CONVERT(datetime, date_added, 101)) >= CONVERT('07/01/2011', date_added, 101))

Storing just Month and Year in SQL Server 2008?

Is it possible to save the month/year in SQL Server 2008 with a regular datetime? I don't need a time stamp and the column is going to store unique mo/yr combinations (i.e. 10-11, 11-11, 12-11, etc,.).
Any recommendations?
Without knowing the intended use, it is not possible to advise correctly. However, storing month and year is easily done in at least three ways:
use a date field, but always store into it the first day of the month at midnight; then always custom format the date field for display
add integer year and month fields, and populate them by splitting a date
add an integer field where you encode it as year * 100 + month or some other useful scheme
Sql Server will store the datetime data in its entirety (year-month-day hour:min:sec.milliSec) no matter what.
When you store your dates, you can make the day the 1st of the month. Just format the dates how you want when you do your queries.
http://www.sql-server-helper.com/tips/date-formats.aspx
From SQLServer 2008 and onwards:
Save as a Date column and add the following check constraint to make sure the value is always the first of the month:
datepart(month, MyDate)<>datepart(month,dateadd(day, -1, MyDate))
You cant only store year and month in a DateTime column. Well, what you can do is default the rest of the values. ie: 2011.10.1.1 , 2011.11.1.1 like that.
Or you can store it as string.
SELECT RIGHT(CONVERT(VARCHAR(10), GETDATE(), 105), 7) AS [MM-YYYY]
You should try this

SQL date format issue in select query

I have an ASP page which will fetch records from a SQL server DB table. The table "order_master" has a field called order_date. I want to frame a select query to fetch order date > a date entered by user(ex : 07/01/2008)
I tried with convert and cast, but both are not working. The sample data in order_date column is 4/10/2008 8:27:41 PM. Actually, I dont know what type it is (varchar/datetime).
Is there any way to do that?
I'd check to make sure that the SQL datatype is a DateTime or SmallDateTime first, then I'd check to make sure that you're passing in a Date/DateTime value from the page.
If those are both correct, then you'd probably be better off following Joel's advice and explicitly convert both values to dates before trying the comparison. Also, check the precision of the time values that you're looking at; it seems obvious, but 1/1/2008 12:00:00.001 AM will not be equal to 1/1/2008 12:00:00.000 AM. Yes, I am speaking from experience. :P
the 07/01/2008 date is the British/French annotation, so all you need to do is:
SELECT myColumn FROM myTable WHERE myDateField >= convert(datetime, '07/01/2008 00:00:00', 103)
this code will get all rows where myDateField has the date 7th of January 2008, since 00:00:00 (hh:mm:ss) so, the first second on that day... in simple words, the entire day.
for more info, check Books online on MSDN
You could create a stored procedure like this
CREATE PROCEDURE GetOrders
#OrderDate DATETIME
AS
SELECT
*
FROM order_master
WHERE Order_Date > #OrderDate
GO
Then you can just convert the users input to a date before calling the stored procedure via your ASP code.
Edit
I just noticed the remark about the column type, you can run this command
sp_help order_master
to get column information to find the data type of order_date.
Have you tried CONVERT()'ing both values to a datetime type?
Remember that when comparing dates, 4/10/2008 8:27:41 PM is not equal to 4/10/2008. SQL Server will interpret 4/10/2008 to mean 4/10/2008 12:00:00 AM, and do an exact comparison down to the second. Therefore 4/10/2008 is LESS THAN 4/10/2008 8:27:41 PM
You state you don't know the field type. That would be the first problem to solve, find out. You can do that with:-
SELECT DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Order_Master' AND
COLUMN_NAME = 'Order_Date'
If its not one of the datetime types it should be converted, if that isn't your responsibility then get on to someone who does have the responsibility.
The fact that you are concerned about the 'format' of the date indicates that you may be building the SQL using concatenation. If so stop doing that. Use a command with a parameter and pass in the date as date type.
Now your issue is one of how the date is entered at the client end and getting it into an unambigous format that can be parsed as a date in the ASP code.
If that is not something you have solved add a comment to this answer and I'll expand this answer.