Feeds:
Posts
Comments

Posts Tagged ‘GENERATE_SERIES() Function’

To test any functionality in SQL Server, we need sample databases to test different scenarios. Few of the sample databases are already available as shown below and you can download and use for FREE.

  1. AdventureWorks
  2. WideWorldImporters
  3. Northwind
  4. Pubs

Sometimes, we need a customized sample table to test one of the SQL Server features. In such cases, above mentioned sample databases are not enough. So we need to create our own test table with some data too. Since there was no proper function available to generate a sample table in earlier version of SQL Server (before 2022), we used CAST(), RAND() and many other functions to achieve it somehow.

In SQL Server 2022, a new function came called GENERATE_SERIES(), which was a long awaited function. One of the usages of this function is that it can easily generate sample table having as much data as we want.

Compatibility Level:

Your database compatibility level MUST be 160 or higher to use this function. Given below is the query to change your database compatibility level.

ALTER DATABASE tempdb SET COMPATIBILITY_LEVEL = 160

Let me show you in the below example, how can we use GENERATE_SERIES() function to generate sample table in SQL Server 2022.

Example :

USE tempdb
GO

CREATE TABLE [Customers]
(
 [CustomerID]         INT,
 [CustomerName]       VARCHAR(250),
 [RegistrationDate]   DATE,
 [EmailAddress]       VARCHAR(100),
 [Address]            VARCHAR(500),
 [PhoneNumber]        VARCHAR(100),
 [DiscountPercentage] NUMERIC(18,6)
);
GO

DECLARE @Start INT = 1;    --Starting point of the record
DECLARE @Stop  INT = 1000; --Ending point of the record

INSERT INTO [Customers]
(
 [CustomerID],
 [CustomerName],
 [RegistrationDate],
 [EmailAddress],
 [Address],
 [PhoneNumber],
 [DiscountPercentage]
)

SELECT  
  value                                           AS [CustomerID]
, CONCAT('John',' - ',value)                      AS [CustomerName]
, DATEADD(day,value,'1753-01-01')                 AS [RegistrationDate]
, CONCAT('John',value,'@raresql.com')             AS [EmailAddress]
, CONCAT(value,' N. 10th Street')                 AS [Address]
, '1 (11) '+ RIGHT(CONCAT('0000000000',value),11) AS [PhoneNumber]
, CONVERT(NUMERIC(18,6),value)/@Stop              AS [DiscountPercentage]

FROM GENERATE_SERIES(@Start,@Stop);
GO

SELECT * FROM [Customers];
GO
--OUTPUT

Clean Up:

In order to clean up the table, we need to drop it as shown below.

USE DATABASE tempdb
GO

DROP Table [Customers];
GO

Conclusion:

I used GENERATE_SERIES() function to generate the sample table and I noticed that it has reduced a lot of complexity in creating sample table, compared to earlier approach. Do let me know if you have generated sample table and what was the approach.

Read Full Post »

Quite often we need to generate a calendar table in our database for reporting purposes with a specific date range. We may generate it for a month, a quarter or a year depending upon our requirements. Since there was no proper function available to generate calendar table in earlier version of SQL Server (Earlier than 2022), we used DATEADD(), DATEDIFF() to achieve it somehow.

In SQL Server 2022, a new function came called GENERATE_SERIES(), which was a long awaited function. One of the usages of this function is that it can easily generate calendar table between two specific dates without using any additional functions.

Let me show you in the below example, how we can use GENERATE_SERIES() function to generate calendar table in SQL Server 2022.

Compatibility Level:

Your database compatibility level MUST be 160 or higher to use this function. Given below is the query to change your database compatibility level.

ALTER DATABASE tempdb SET COMPATIBILITY_LEVEL = 160

Example :


CREATE TABLE tbl_Calendar
(
  [ID]             INT IDENTITY
, [Date]           DATE
, [Day]            INT
, [DayShortName]   VARCHAR(100)
, [DayName]        VARCHAR(100)
, [Week]           INT
, [MonthShortName] VARCHAR(100)
, [Month]          INT
, [MonthName]      VARCHAR(100)
, [Quarter]        INT
, [QuarterName]    VARCHAR(100)
, [Year]           INT
);
GO

DECLARE @SetStartDate DATE, @Start INT, @Stop INT, @Step INT;

SET @SetStartDate = '2022-01-01' --Start date of the calender;
SET @Start   = 0;
SET @Stop    = 365 -- No of days(one year) ;
SET @Step    = 1;

INSERT INTO tbl_Calendar
( 
  [Date]
, [Day]
, [DayShortName]
, [DayName]
, [Week]
, [MonthShortName]
, [Month]
, [MonthName]
, [Quarter]
, [QuarterName] 
, [Year]
)
SELECT DATEADD(DAY,value,@SetStartDate) AS [Date]
     , DATEPART(DAY,DATEADD(DAY,value,@SetStartDate)) AS [Day]
	 , FORMAT(DATEADD(DAY,value, @SetStartDate) ,'ddd') AS [DayShortName]
	 , DATENAME(WEEKDAY,DATEADD(WEEKDAY,value,@SetStartDate)) AS [DayName]
     , DATEPART(WEEK,DATEADD(DAY,value,@SetStartDate)) AS [Week]
	 , FORMAT(DATEADD(DAY,value, @SetStartDate) ,'MMM') AS [MonthShortName]
	 , MONTH(DATEADD(DAY,value,@SetStartDate)) AS [Month]
     , DATENAME(MONTH,DATEADD(DAY,value,@SetStartDate)) AS [MonthName]
	 , DATEPART(QUARTER,DATEADD(DAY,value,(@SetStartDate))) AS [Quarter]
	 , CONCAT('Quarter - ',DATEPART(QUARTER,DATEADD(DAY,value,(@SetStartDate)))) AS [QuarterName]
     , YEAR(DATEADD(DAY,value,@SetStartDate)) AS [Year]
FROM GENERATE_SERIES(@Start,@Stop,@Step) 
GO

SELECT * FROM tbl_Calendar;
GO

--OUTPUT

Conclusion:

I used GENERATE_SERIES() function to create calendar table and I noticed that it has reduced a lot of complexity in creating the calendar table, if we compare it with earlier approach. Do let me know, if you have generated calendar table and what was the approach.

Read Full Post »

Sometimes we come across a case where we need to generate a number series in SQL Server between two numbers. For example, if you give a week’s start date and end date and you need to generate whole week’s dates, it was not easy since there was no specific function available to generate series in earlier version of SQL Server (Earlier than SQL Server 2022).

In SQL Server 2022, a new function shipped namely GENERATE_SERIES() which was a long awaited function. This function will allow us to generate series of numbers between two numbers.

  • Old Approach (Earlier than SQL Server 2022):

Let me demonstrate how we used to struggle to generate number series in earlier versions of SQL Server, we used common table expression, Union All and a lot of other techniques to generate, it as shown below.

DECLARE @StartRange INT = 1;
DECLARE @EndRange   INT = 10; 

;WITH CTE AS (
     SELECT @StartRange AS Sno 
	 UNION ALL 
	 SELECT Sno+1 FROM CTE WHERE Sno+1 <= @EndRange ) 
SELECT * FROM CTE; 
GO
--OUTPUT

  • New Approach (SQL Server 2022 & Above):

Compatibility Level:

Your database compatibility level MUST be 160 or higher to use this function. Given below is the query to change your database compatibility level.

 ALTER DATABASE tempdb SET COMPATIBILITY_LEVEL = 160 

Example 1:

In this example, I will show you how to generate series between two numbers with the newly introduced function GENERATE_SERIES(). This function generates the series of numbers between the start and end numbers and takes the steps needed to jump from start until end.

DECLARE @Start INT = 1;
DECLARE @Stop  INT = 10;
DECLARE @Step  INT = 1;

SELECT value FROM 
GENERATE_SERIES(@Start,@Stop,@Step);
GO
--OUTPUT

Default:

By Default, Step value is 1 in such cases, where start number is less than stop number, so we can achieve the same output as mentioned above without passing Step parameter as shown below.

DECLARE @Start INT = 1;
DECLARE @Stop  INT = 10;


SELECT value FROM 
GENERATE_SERIES(@Start,@Stop);
GO
--OUTPUT

Issue:

When you want to generate series in ascending order then DON’T put NEGATIVE value in Step parameter. Even if you put negative value in Step parameter, it will not generate error but it will not give you any result as shown below.

DECLARE @Start INT = 1;
DECLARE @Stop  INT = 10;
DECLARE @Step  INT = -1;

SELECT value FROM 
GENERATE_SERIES(@Start,@Stop,@Step);
GO
--OUTPUT

Example 2:

In this example, I will show you, how to generate number series in descending order using GENERATE_SERIES() function.

DECLARE @Start INT = 10;
DECLARE @Stop  INT = 1;
DECLARE @Step  INT = -1;

SELECT value FROM 
GENERATE_SERIES(@Start,@Stop,@Step);
GO

--OUTPUT

Default:

By Default, Step value is -1 in such cases, where stop number is less than start number, so we can achieve the same output as mentioned above without passing Step parameter as shown below.

DECLARE @Start INT = 10;
DECLARE @Stop  INT = 1;

SELECT value FROM 
GENERATE_SERIES(@Start,@Stop);
GO
--OUTPUT

Issue:

When you want to generate series in descending order then DON’T put POSITIVE value in Step parameter. Even if you put positive value in Step parameter, it will not generate error but it will not give you any result as shown below.

DECLARE @Start INT = 10;
DECLARE @Stop  INT = 1;
DECLARE @Step  INT = 1;

SELECT value FROM 
GENERATE_SERIES(@Start,@Stop,@Step);
GO
--OUTPUT

Example 3:

If we want to generate negative number series using GENERATE_SERIES() function then the query and output will be like this.

DECLARE @Start INT = -1;
DECLARE @Stop  INT = -10;
DECLARE @Step  INT = -1;

SELECT * FROM 
GENERATE_SERIES(@Start,@Stop,@Step);
GO
--OUTPUT

Example 4:

In this example, I will show you how to generate Odd numbers series using GENERATE_SERIES() function.

DECLARE @Start INT = 1;
DECLARE @Stop  INT = 10;
DECLARE @Step  INT = 2;

SELECT value FROM 
GENERATE_SERIES(@Start,@Stop,@Step);
GO
--OUTPUT

Example 5:

In this example, I will show you how to generate Even numbers series using GENERATE_SERIES() function.

DECLARE @Start INT = 0;
DECLARE @Stop  INT = 10;
DECLARE @Step  INT = 2;

SELECT value FROM 
GENERATE_SERIES(@start,@stop,@step);
GO--OUTPUT

Conclusion:

I found GENERATE_SERIES() function very useful. Earlier we used multiple functions to generate the series between two numbers but now we can easily achieve with the help of GENERATE_SERIES() function. Do let me know if you will use this function and how you found it.

Read Full Post »