I'm pulling the data from SQL database. I have a couple columns with date which need to be converted into Int type, but when I do this the date changes (-2 days). I tried Cast and Convert and it's always the same.
Converting to other type works fine and returns the correct date, but doesn't work for me. I need only the date part from datetime and it needs to be recognised as a date by Excel.
Why is this happening? Any ideas how to get it sorted?
I'm using the following query:
SELECT wotype3, CONVERT(INT,wo_date2 ,103), CAST(duedate AS int) FROM Tasks WHERE
duedate > DATEADD(DAY,1, GETDATE())
AND wo_date2>0
AND wo_date2<DATEADD(WEEK,3,GETDATE())
ORDER BY wotype3
I've had big problems with this, checking my SQL Server's calculation results with "expected results" which a user had created using Excel.
We had discrepancies just because of this 2-day date difference.
Why does it happen ?
Two reasons:
SQL Server uses a zero-based date count from Jan 1 1900, but Excel uses a 1-based date count from Jan 1 1900.
Excel has a bug in it (gasp!) which makes it think that the year 1900 was a leap year. It wasn't. SQL Server correctly refuses to let you have a date value containing "29-Feb-1900".
Combine these two discrepancies, and this is why all dates, from March 1 1900 onwards, are always 2-days out.
Apparently, this Excel bug is a known issue, to keep it in line with Lotus 1-2-3.
The Intentional Date Bug
Microsoft's own explanation
From now on, I think I'll justify bugs in my code with the same excuse.
;-)
For SQL Server 2008 and above, you can use the DATE datatype.
declare #dt datetime = '12/24/2013 10:45 PM' -- some date for example
SELECT #dt as OriginalDateTime, CAST(#dt as DATE) as OnlyDate
For versions prior to SQL Server 2008, you would need to truncate the time part using one or the other functions. Here is one way to do that:
declare #dt datetime = '12/24/2013 10:45 PM' -- some date for example
SELECT #dt as OriginalDateTime, CAST(FLOOR(CAST(#dt AS FLOAT)) as DATETIME) as OnlyDate
Related
ALTER PROCEDURE [dbo].[AccountsData]
#Start_Date datetime,
#End_Date datetime
AS
BEGIN
SET NOCOUNT ON;
SELECT
a.Customer_AC_No, a.Customer_Name, a.Product_Code,
a.Product_Description, a.Sales_Person, c.HSID
FROM
(SELECT
Customer_AC_No, Customer_Name, Product_Code,
Product_Description, Sales_Person
FROM
View_Sales_Details
WHERE
([Week Ending] >=' #Start_Date') AND ([Sales Value] > 0)
GROUP BY
Customer_AC_No, Product_Code, Product_Description,
Customer_Name, Sales_Person) AS a
LEFT JOIN
(SELECT
Customer_AC_No, Product_Code
FROM
View_Sales_Details
WHERE
([Week Ending] >= '#End_Date') AND ([Sales Value] > 0)
GROUP BY
Customer_AC_No, Product_Code) AS b ON a.Customer_AC_No = b.Customer_AC_No
AND a.Product_Code = b.Product_Code
INNER JOIN
Hubspot.dbo.View_BPA_Cust_Data AS c ON a.Customer_AC_No = c.CustomerNo COLLATE Latin1_General_100_CI_AS
WHERE
b.Customer_AC_No IS NULL
ORDER BY
a.Customer_AC_No, a.Product_Code ASC
END
I am trying to pass the above date parameters to the SQL Server stored procedure above, but I keep getting this error
Msg 241, Level 16, State 1, Procedure AccountsData, Line 52
Conversion failed when converting date and/or time from character string.
Can some one please help. WeekEnding date is also in datetime format. Thanks
There are many formats supported by SQL Server for specifying a date&time as a string literal - see the MSDN Books Online on CAST and CONVERT. Most of those formats are dependent on what settings you have - therefore, these settings might work some times - and sometimes not.
The way to solve this is to use the (slightly adapted) ISO-8601 date format that is supported by SQL Server - this format works always - regardless of your SQL Server language and dateformat settings.
The ISO-8601 format is supported by SQL Server comes in two flavors:
YYYYMMDD for just dates (no time portion); note here: no dashes!, that's very important! YYYY-MM-DD is NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:MM:SS for dates and times - note here: this format has dashes (but they can be omitted), and a fixed T as delimiter between the date and time portion of your DATETIME.
This is valid for SQL Server 2000 and newer.
If you use SQL Server 2008 or newer and the DATE datatype (only DATE - not DATETIME!), then you can indeed also use the YYYY-MM-DD format and that will work, too, with any settings in your SQL Server.
Don't ask me why this whole topic is so tricky and somewhat confusing - that's just the way it is. But with the YYYYMMDD format, you should be fine for any version of SQL Server and for any language and dateformat setting in your SQL Server.
The recommendation for SQL Server 2008 and newer is to use DATE if you only need the date portion, and DATETIME2(n) when you need both date and time. You should try to start phasing out the DATETIME datatype if ever possible.
So in your case, either switch to using DATE as your parameter datatype (since you obviously don't use the time portion):
ALTER PROCEDURE [dbo].[AccountsData]
#Start_Date DATE,
#End_Date DATE
and then execute your stored procedure like this:
EXEC [dbo].[AccountsData] '2019-05-11', '2020-06-10'
or use this format to support DATETIME if you insist on keeping that:
EXEC [dbo].[AccountsData] '2019-05-11T00:00:00', '2020-06-10T00:00:00'
Your have an error in your select. You have change your query like this
DATEPART(wk, Ending)>=DATEPART(wk, #Start_Date) AND ([Sales Value] > 0)
DATEPART(wk, Ending)>=DATEPART(wk, #End_Date) AND ([Sales Value] > 0)
if any date time value provided to sql server can i get it's midnight value with some function in sql server.. for example if i provide 2013/07/03 01:34AM , i want to get it to 2013/07/03 12:00 AM.Is there a way to do it?
SQL Server 2008+
SELECT CAST(CAST('2013/07/03 01:34AM' AS date) AS datetime)
For older versions, see this Best approach to remove time part of datetime in SQL Server Never use anything that requires float or int or varchar conversions
This should give you what you need:
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, InputDateField), 0)
Should be slightly quicker than cast:
Most efficient way in SQL Server to get date from date+time?
Hey fellas, I'm having difficulty obtaining only the date from the system and inserting it into a column, is there a built-in function that can acquire it?
On top of that, how do I add years to the current date?
I know I'm pushing it right now, but I'm also wondering what's the format for the date datatype?
Because sometimes I'd like to manually insert values into a column with that type in mind.
Any help would greatly be appreciated.
Thanks.
To get date only (SQL Server 2008 only) CAST to date type
SELECT CAST(GETDATE() AS date)
To add years, use DATEADD
SELECT DATEADD(year, 2, CAST(GETDATE() AS date))
Formats: use yyyymmdd or ISO yyyy-mm-dd (for newer datetime types) for safety.
Read this for everything about date+time in SQL Server
To add a year to the current date, look at the dateadd() function.
To just get the date from sql w/o the time, you can do this:
DECLARE #Date DATETIME
SELECT #Date = CONVERT(VARCHAR, GETDATE(), 101)
SELECT #Date
Sql will implicity convert the VARCHAR back to DATETIME. Look up the CONVERT function in BOL and it will give you all kinds of different styles for the 3rd parameter.
Bender
This is related to Floor a date in SQL server, but I'm taking it one step further:
I'm writing a query on a SQL Server table and I want to get all records for the current calendar year and the previous calendar year. So, right now, I'd want a query to return all records between January 1st, 2008 and today. But come January 1st, 2010, I want it to return records no older than 2009.
Essentially, I want to floor the current date to the beginning of the year and then subtract 1.
After rummaging through some SQL Server documentation, I came up with this:
WHERE create_date >= CAST((CAST(YEAR(GETDATE()) AS int) -1) AS varchar)
but it feels kind of ugly. Is there a better way?
Why not just use the year function on create_date as well?
WHERE YEAR(create_date) >= (YEAR(GETDATE()) -1)
This assumes (as you did) that there are no records in the database greater than today's date
I would suggest assigning a variable with the date lastyear-01-01, either by making an UDF for it, or something like
DECLARE #startOfLastYear DATETIME
SET #startOfLastYear = CAST(YEAR(GETDATE()) - 1 AS VARCHAR) + '-01-01'
Then do the query:
WHERE create_date >= #startOfLastYear
Because of two reasons:
Using YEAR() or any other function
on data from tables (i.e.
YEAR(create_date)) makes indices
unusable and decreases the
performance of the query
The variable name tells exactly what it is, and reading the code is easier.
Surely there is a way to store a date value prior than 1-1-1900 in a column other than varchar? Or do I really have to break this out, and perform my own datetime library for date differences, sorting, and such?
Yes, I understand how datetime's are actually stored (an integer value from a specific date), but I remember there being another workaround from years ago. It's just slipping me now.
smalldatetime vs. datetime!
http://msdn.microsoft.com/en-us/library/ms187819.aspx
http://msdn.microsoft.com/en-us/library/ms182418.aspx
!
Yes the SQL Server DateTime type can store dates from 1 January 1753.
SQL Server 2008 has the DATE data type which can range from 0001-01-01 through 9999-12-31.
With previous versions, your SOL if you need a date prior to 1753-01-01 (Minimum value for DATETIME).