Generate datetime range SQL Server 2000 - sql-server

I am trying to generate dates for the whole year of 2012 in datetime format to store in a SQL Server table in a datetime column.
How is that done?
So start date would be 1/1/2012 until 31/12/2012 but in the correct format. I am assuming I should have 365 rows generated. Any idea?

CREATE TABLE DateTimeRange2012([Date] DATETIME NOT NULL)
GO
INSERT INTO DateTimeRange2012([Date])
SELECT DATEADD(day, Number, '20120101')
FROM master..spt_values
WHERE Number < 366 AND type = 'P'
Much more clear for keeping the values persisted?

Nice answer from Oleg Dok.
To expand upon his answer, here's a stored procedure that accepts a year and generates all of the dates for the year. This takes into account leap years.
CREATE PROCEDURE GenerateDates (#Year INT)
AS
SET NOCOUNT ON
DECLARE #FirstDate DATETIME
DECLARE #NoOfDates INT
SET #FirstDate = DateAdd(Year, #Year-1900, 0)
IF MONTH(DATEADD(Day, 59, #FirstDate))=3
SET #NoOfDates = 365
ELSE
SET #NoOfDates = 366
INSERT INTO DateTimeRange([Date])
SELECT DATEADD(day, Number, #FirstDate)
FROM master..spt_values
WHERE Number < #NoOfDates AND type = 'P'
One proviso. I believe that "spt_values" may not be supported and may be removed in future versions of SQL Server. However, I have read that it is being used in SQL Server 11 example code so perhaps it's not a worry just yet.

Related

SQL Server stored procedure passing date parameters

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)

SQL Server : get previous day results using UNIX Timestamp

Using SQL Server 2016, I have a table that contains a column DateTime of type INT which contains a UNIX timestamp. So if I want to get all the rows where the timestamp is yesterday, I know I need to check if the timestamp is >= the timestamp for 'yesterday at 00:00' and <= 'yesterday at 23:59'.
How can I do this with SQL Server 2016?
Found a few examples but they where for MySQL. I did find this example below. But it throws an error, so I'm probably not using it correctly. Or actually, this might be MySQL as well...
WHERE [DateTime] <= DATEADD(day, -1, convert(day, GETDATE()))
Any help would be greatly appreciated!
Here's my solution that seems to work. Did a test manually where I checked if the timestamp was between 1596513600 and 1596599940, and got the same output from the Solution below:
Function to Convert Timestamp to datetime type (*adjusts for Local time):
CREATE FUNCTION dbo.fn_ConvertToDateTime (#Datetime int)
RETURNS DATETIME
AS
BEGIN
DECLARE #LocalTimeOffset BIGINT
,#AdjustedLocalDatetime BIGINT;
SET #LocalTimeOffset = DATEDIFF(second,GETDATE(),GETUTCDATE())
SET #AdjustedLocalDatetime = #Datetime - #LocalTimeOffset
RETURN (SELECT DATEADD(second,#AdjustedLocalDatetime, CAST('1970-01-01 00:00:00' AS datetime)))
END;
GO
SQL Statement:
SELECT *
FROM dbname.dbo.Tablename
WHERE dbo.fn_ConvertToDateTime([DateTime]) >= dateadd(day,datediff(day,1,GETDATE()),0)
AND dbo.fn_ConvertToDateTime([DateTime]) < dateadd(day,datediff(day,0,GETDATE()),0)
The Resulting output shows only Rows that contain a unix timestamp from Yesterday.

Why can't I use a datetime parameter in ssrs?

I have an SSRS Date/Time parameter generated from a shared dataset query against a SQL Server datetime field. The parameter displays correctly in a report textbox but it will not work in an embedded dataset query, even against the same table that the datetime value was generated from.
In order to use the parameter for a dataset query I have to parse both sides of a where clause to get it to work in Preview in SSDT:
(convert(varchar,invoice.snapshot_datetime,120)) = (convert(varchar,#snapshotdatetime,120))
This is tremendously inefficient.
How can I get my where clause to work without parsing the invoice.snapshot_datetime column?
Server Details
The SQL Server Language is English (United States).
SQL Server dateformat is mdy (from dbcc useroptions).
Getdate() returns '2015-05-20 10:27:56.687' in SSMS
Assuming your date range is between 1900-01-01 and 2079-06-06 you can cast to SmallDateTime to truncate the seconds out of your datetime variable:
DECLARE #DateTime datetime
SET #DateTime = CAST(CAST(#snapshotdatetime as SmallDateTime) as DateTime)
(thanks to t-clausen.dk for his answer here)
Now, since your actual column is of type DateTime, it does keep seconds (and milliseconds), and you will need to eliminate them as well.
However, using functions on your column will prevent the SQL Server from using any indexes you might have on this column, so a better approach would be to use a DateTime range:
DECLARE #FromDateTime datetime, #ToDateTime datetime
SET #FromDateTime = CAST(CAST(#snapshotdatetime as SmallDateTime) as DateTime)
Since the cast will round the minutes of the small date time up if it's over 29.998 seconds, and down if it's below 29.999 seconds. You always want to round down since it's From datetime, you need to cheke if you need to decrease a minute:
IF datepart(second, #snapshotdatetime) > 29
OR (datepart(second, #snapshotdatetime) = 29
AND datepart(millisecond, #snapshotdatetime) > 998)
SET #FromDateTime = DATEADD(minute, -1, #FromDateTime)
SET #ToDateTime = DATEADD(minute, 1, #FromDateTime)
and then, in your where clause, use this:
invoice.snapshot_datetime <= #FromDateTime
AND invoice.snapshot_datetime >= #ToDateTime
If you haven't found solution yet, try this:
select (convert(varchar,GETDATE(),112))
it will return 20180206 (yyymmdd)

Excel incorrectly converts Date into Int

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

SQL Server function to return minimum date (January 1, 1753)

I am looking for a SQL Server function to return the minimum value for datetime, namely January 1, 1753. I'd rather not hardcode that date value into my script.
Does anything like that exist? (For comparison, in C#, I could just do DateTime.MinValue)
Or would I have to write this myself?
I am using Microsoft SQL Server 2008 Express.
You could write a User Defined Function that returns the min date value like this:
select cast(-53690 as datetime)
Then use that function in your scripts, and if you ever need to change it, there is only one place to do that.
Alternately, you could use this query if you prefer it for better readability:
select cast('1753-1-1' as datetime)
Example Function
create function dbo.DateTimeMinValue()
returns datetime as
begin
return (select cast(-53690 as datetime))
end
Usage
select dbo.DateTimeMinValue() as DateTimeMinValue
DateTimeMinValue
-----------------------
1753-01-01 00:00:00.000
Have you seen the SqlDateTime object? use SqlDateTime.MinValue to get your minimum date (Jan 1 1753).
As I can not comment on the accepted answer due to insufficeint reputation points my comment comes as a reply.
using the select cast('1753-1-1' as datetime) is due to fail if run on a database with regional settings not accepting a datestring of YYYY-MM-DD format.
Instead use the select cast(-53690 as datetime) or a Convert with specified datetime format.
Enter the date as a native value 'yyyymmdd' to avoid regional issues:
select cast('17530101' as datetime)
Yes, it would be great if TSQL had MinDate() = '00010101', but no such luck.
Here is a fast and highly readable way to get the min date value
Note: This is a Deterministic Function, so to improve performance further we might as well apply WITH SCHEMABINDING to the return value.
Create a function
CREATE FUNCTION MinDate()
RETURNS DATETIME WITH SCHEMABINDING
AS
BEGIN
RETURN CONVERT(DATETIME, -53690)
END
Call the function
dbo.MinDate()
Example 1
PRINT dbo.MinDate()
Example 2
PRINT 'The minimimum date allowed in an SQL database is ' + CONVERT(VARCHAR(MAX), dbo.MinDate())
Example 3
SELECT * FROM Table WHERE DateValue > dbo.MinDate()
Example 4
SELECT dbo.MinDate() AS MinDate
Example 5
DECLARE #MinDate AS DATETIME = dbo.MinDate()
SELECT #MinDate AS MinDate
It's not January 1, 1753 but select cast('' as datetime) wich reveals: 1900-01-01 00:00:00.000 gives the default value by SQL server.
(Looks more uninitialized to me anyway)
This is what I use to get the minimum date in SQL Server. Please note that it is globalisation friendly:
CREATE FUNCTION [dbo].[DateTimeMinValue]()
RETURNS datetime
AS
BEGIN
RETURN (SELECT
CAST('17530101' AS datetime))
END
Call using:
SELECT [dbo].[DateTimeMinValue]()
What about the following?
declare #dateTimeMin as DATETIME = datefromparts(1753, 1, 1);
select #dateTimeMin;
The range for datetime will not change, as that would break backward compatibility. So you can hard code it.

Resources