Create a Test Table
For this step we will create a test table: dbo.TestDate and load it with sample data. Here is the T-SQL syntax:
Use Tempdb; CREATE TABLE [dbo].[TestDate] ( [ID] [int] IDENTITY(1,1) NOT NULL, [MyDate] [date] NULL, -- date columm [CharDate] [char](8) NULL, -- date columm [MyDateTime] [datetime] NULL -- date columm ) ON [PRIMARY]; GO
Load Sample Test Data
For this limited example we will only load 20 rows of test data. For the data load to convert the date to 'yyyymmdd' format, I will use CONVERT(CHAR(8), TheDate, 112). Format 112 is the ISO standard for yyyymmdd.
SET NOCOUNT ON; DECLARE @SetDateTime DATETIME = '2020-01-01 14:04:03.230'; -- current date INSERT INTO [dbo].[TestDate] ([MyDate],[CharDate],[MyDateTime]) SELECT CAST(Convert(CHAR(8),@SetDateTime,112) as DATETIME), Convert(CHAR(8),@SetDateTime,112), CAST(Convert(CHAR(8),@SetDateTime,112) as DATETIME); INSERT INTO [dbo].[TestDate] ([MyDate],[CharDate],[MyDateTime]) SELECT @SetDateTime, Convert(CHAR(8),@SetDateTime,112), @SetDateTime GO INSERT INTO [dbo].[TestDate] ([MyDate] ,[CharDate], [MyDateTime]) SELECT top 1 [MyDateTime]+1, Convert(CHAR(8),[MyDateTime]+1,112), [MyDateTime]+1 FROM [dbo].[TestDate] ORDER BY 1 desc GO 20 --load 20 days of dates
Results: Example SQL Server dates loaded.
Convert Dates to Char 'yyyymmdd'
Next, converting a DATE and DATETIME datatype to character 8 'yyyymmdd' output using CONVERT and FORMAT functions.
--A. CONVERT use style = 112 to CHAR 8 or NCAHR 8 SELECT CONVERT(CHAR(8),[MyDate],112) as 'MyDate',CONVERT(CHAR(8),[MyDateTime],112) as 'MyDateTime' FROM [dbo].[TestDate]; --B. NCHAR(8) SELECT CONVERT(NCHAR(8),[MyDate],112) as 'MyDate',CONVERT(NCHAR(8),[MyDateTime],112) as 'MyDateTime' FROM [dbo].[TestDate]; --C. FORMAT Function (new in SQL 2012) use format = yyyyMMdd returning the results as nvarchar. SELECT FORMAT([MyDate],'yyyyMMdd') as 'MyDate', FORMAT([MyDateTime],'yyyyMMdd') as 'MyDateTime' FROM [dbo].[TestDate];
Results: The results of the 3 queries all show the conversion to 'yyyymmdd' regardless of the format or the conversion method. The results below were reduced to 3 rows each for the demo.
Convert Char 'yyyymmdd' back to Date data types in SQL Server
Now, convert the Character format 'yyyymmdd' to a Date and DateTime data type using CAST and CONVERT.
--A. Cast and Convert datatype DATE: SELECT [CharDate], CAST([CharDate] AS DATE) as 'Date-CAST', CONVERT(DATE,[CharDate]) as 'Date-CONVERT' FROM [dbo].[TestDate]; --B. Cast and Convert datatype DATETIME: SELECT [CharDate], CAST([CharDate] AS DATETIME) as 'DateTime-CAST', CONVERT(DATETIME,[CharDate]) as 'DateTime-CONVERT' FROM [dbo].[TestDate];
Results: Below shows the results of converting CHAR 'yyyymmdd' to a DATE and DATETIME data types! SQL does this gracefully.
Filtering Dates by Char 'yyyymmdd' and the Gotcha
Using Character 'yyyymmdd' as a filter in the WHERE clause against date datatypes.
-- Test 'YYYYMMDD' filter against Date datatypes --A. DATE datatype SELECT [MyDate] FROM [dbo].[TestDate] WHERE [MyDate] = '20200101' --B. DATETIME datatype SELECT [MyDateTime] FROM [dbo].[TestDate] WHERE [MyDateTime] = '20200101' --implicit conversion to datetime Midnight!;
Results: Note the difference in the 2 result sets. When filtering against a DATETIME datatype, SQL implicitly converts the Character and appends a Midnight timestamp. Any rows with MyDateTime value other than midnight are excluded, i.e. 2020-01-01 14:04:03.230. This is the 'Gotcha'!
How to use Char 'yyyymmdd' filter against Datetime datatype to adjust for the Gotcha
When using the 'yyyymmdd' in the filter against DateTime datatype you must account for the timestamp part of the datatype!
--A. Use Greater Than and Equal and Less Than to get all dates with a Char 'yyyymmdd' Filter: SELECT * FROM [dbo].[TestDate] WHERE [MyDateTime] >= '20200101' AND [MyDateTime] < '20200102' --implicit conversion to datetime Midnight!;
What happens if we filter with yyyyymmdd as an Integer value?
--A. Test yyyymmdd filter against Date datatype using and integer SELECT * FROM [dbo].[TestDate] WHERE [MyDate] = 20200101;
Results: We can't do this because it results in an error!
Alternative Formats
Last, I will share examples of alternative formats for returning dates. Also, I will show how robust SQL is at converting the other formats when used in a where clause.
--A. Alternative formats that returns Year Month Day mixing Date and Datetime formats using CONVERT: SELECT CONVERT(CHAR(10),[MyDate],120) as 'MyDate_w_Dash', CONVERT(CHAR(10),[MyDateTime],111) as 'MyDateTime_w_Slash', CONVERT(CHAR(10),[MyDateTime],102) as 'MyDateTime_w_Dot' FROM [dbo].[TestDate]; --B. Alternative formates that returs Year Month Day mixing Date and Datetime formats using FORMAT: SELECT FORMAT([MyDate],'yyyy-MM-dd') as 'MyDate_w_Dash', FORMAT([MyDate],'yyyy/MM/dd') as 'MyDate_w_Slash', FORMAT([MyDateTime],'yyyy.MM.dd') as 'MyDateTime_w_Dot' FROM [dbo].[TestDate]; --C. Note using Year, month, day in the where clause that SQL server will recognize different delimiters: dash, slash, dot or no delimiter as shown above. SELECT * FROM [dbo].[TestDate] WHERE [MyDateTime] = '2020.01.01' --or '2020/01/01' or '2020-01-01' or '20200101' ;
Results: Review the 3 result sets from the queries! Note the different date delimiters and the ability to use different delimited dates as filters.
Wrap Up
I hope you enjoyed this exercise on year, month, day date formats and can see the flexibility that SQL Server has handling dates. Other ways to take advantage of the Year Month Day short format, might include concatenating a date to a file name or naming a monthly billing batch. I have also seen the use of Char(6) YYYYMM to denote financial monthly periods. Please comment on other ways you may have used the yyyymmdd date format!