Feeds:
Posts
Comments

Archive for the ‘Functions’ Category

In SQL Server 2022, an enhancement came in STRING_SPLIT() function, which was a long awaited functionality. This enhancement provides a new column name ordinal, which has row number for each string split by this function.

Let me create a sample to demonstrate the functionality of new ordinal column in STRING_SPLIT() function as shown below.

Sample:

USE tempdb
GO
   
CREATE TABLE #Employee
(
 EmployeeID     INT IDENTITY(1,1),
 EmployeeName   VARCHAR(500),
 EmailAddresses VARCHAR(500)
);
GO
   
INSERT INTO #Employee(EmployeeName, EmailAddresses)
VALUES
('John', 'John_1@gmail.com;John_2@gmail.com;John_3@hotmail.com'),
('Sarah', 'Sarah_1@gmail.com;Sarah_2@hotmail.com;Sarah_3@gmail.com'),
('Aaron', 'Aaron_1@gmail@com;Aaron_2@hotmail.com'),
('Ackerman', 'Ackerman_1@gmail.com;Ackerman_2@hotmail.com');
GO

SELECT * FROM #Employee;
GO
--OUTPUT

Example 1:

In the below example, I will split the string in email addresses column based on a separator as usual. Also, I will pass the third argument (which came in SQL 2022 as an ehancement) as 1 in STRING_SPLIT() function which means that STRING_SPLIT() will not only split the string but also provide a serial number (ordinal column) against each split string as shown below.

USE tempdb
GO

SELECT EmployeeID
     , EmployeeName
 , value AS EmailAddress
 , Ordinal
FROM   #Employee
CROSS APPLY STRING_SPLIT(EmailAddresses, ';', 1);
GO
--OUTPUT

Example 2:

In this example, I will show you how important is this new column ordinal and how we used to struggle in earlier version of SQL Server (Earlier than 2022) to mimic the same functionality with the help of common table expression & other functions.

Let me grab the first two email addresses for each employee using old and new approach. Both approaches will return the same result but new approach is simple & efficient.

  • Old Approach: (Using ROW_NUMBER() & common table expression)


USE tempdb
GO
 
;WITH CTE AS
(SELECT EmployeeID
      , EmployeeName
      , value AS EmailAddress
      , ROW_NUMBER() OVER(PARTITION BY EmployeeID 
						  ORDER BY EmployeeID ASC) AS Ordinal
FROM    #Employee
CROSS APPLY STRING_SPLIT(EmailAddresses, ';'))
SELECT * FROM CTE WHERE Ordinal<3;
GO
--OUTPUT

  • New Approach: (Using ordinal column)

USE tempdb
GO
 
SELECT EmployeeID
     , EmployeeName
     , value AS EmailAddress
	 , Ordinal
FROM   #Employee
CROSS APPLY STRING_SPLIT (EmailAddresses, ';', 1)
WHERE ordinal<3;
GO
--OUTPUT

Conclusion:

I found the new enhancement of STRING_SPLIT() function very useful, earlier we used common table expression & ROW_NUMBER() functions to find the row number of each split string but now we can easily achieve with the help of STRING_SPLIT() ordinal column. Do let me know if you use ordinal column and how did you find it.

Read Full Post »

Creating a comma separated list from a table or converting multiple rows into single row along with delimiter was never been easier in earlier (before SQL Server 2017) version of SQL Server. I have written a detailed article back in 2012 regarding this issue, where I used CURSOR, COALESCE() function, STUFF() function & XML format etc. to achieve it.

In SQL Server 2017, a new function shipped namely STRING_AGG() which can help you to achieve above mentioned functionality by using this function ONLY. By the way, instead of comma ( , ) you can use semi-colon ( ; ) or any other delimiters, it works like a charm with all delimiters.

Let me demonstrate STRING_AGG() functionality by giving some examples. I am going to use Customers table in Northwind database as shown below, which can be downloaded from here.

Sample:

As you can see in below sample table that there are many companies in each country.

USE Northwind
GO

SELECT [Country]
     , [CompanyName]
FROM   [dbo].[Customers]
ORDER BY [Country];
GO
--OUTPUT

Example 1:

In the below example, I created a company list separated by comma (delimiter) for each country. You can use any delimiter based on your requirement.

USE Northwind
GO

SELECT [Country]
     , STRING_AGG(CompanyName,', ') AS [CompanyName]
FROM   [dbo].[Customers]
GROUP BY [Country]
ORDER BY [Country];
GO
--OUTPUT

Example 2:

In the above example 1, I got comma-separated list of companies for each country but the issue is those company names do NOT display in an alphabetical sort order. To resolve it we are going to use WITHIN GROUP ORDER BY clause within function as shown below:

USE Northwind
GO

SELECT [Country]
       ,STRING_AGG(CompanyName,', ') WITHIN GROUP (ORDER BY CompanyName) AS [CompanyName]
FROM   [dbo].[Customers]
GROUP BY [Country]
ORDER BY [Country];
GO
--OUTPUT

Example 3:

In this example, I want to get list of comma separated OrderID(s) for each Company but the data does NOT exists in one table, so I will join two tables (Customers, Orders) to be able to  retrieve the data as shown below.

USE Northwind
GO

SELECT [CompanyName] 
	  , STRING_AGG(OrderID,',') AS OrderIDs
FROM   [Customers]
INNER JOIN [Orders] ON [Customers].[CustomerID]=[Orders].[CustomerID] 
GROUP BY [CompanyName];
GO
--OUTPUT

Conclusion:

I use STRING_AGG() function in my day to day SQL scripting quite frequently, I found it very handy. Do let me know if you use this function in your development and how did you find it?

Read Full Post »

String concatenation technique is used quite frequently when we are dealing with legacy systems. Sometimes, we need to add a specific delimiter after every column / expression while concatenating multiple columns / expressions. Earlier, we used multiple functions to achieve it and I have written a detailed article about it earlier.

In SQL Server 2017, a new function shipped namely CONCAT_WS() and you can easily achieve the above mentioned scenario by using CONCAT_WS() function. The database compatibility level MUST be 140 or higher to use this function.

Let me create a sample to demonstrate the functionality of CONCAT_WS() function.

Sample:

USE TEST_DB
GO

CREATE TABLE Employees(
EmployeeID INT IDENTITY(1,1),
EmployeeName VARCHAR(100),
PrimaryEmail VARCHAR(100),
SecondaryEmail VARCHAR(100),
AlternateEmail VARCHAR(100)
);
GO

INSERT INTO Employees
(EmployeeName, PrimaryEmail, SecondaryEmail, AlternateEmail)
VALUES
 ('Davolio Nancy', 'Davolio2@gmail.com', 'Davolio_Nancy@gmail.com', 'Nancy99@hotmail.com')
,('Fuller Andrew', 'Fuller_12@gmail.com', 'Andrew_f99@gmail.com', 'Andrew_f9@hotmail.com')
,('Leverling Janet', 'Leverling_42@gmail.com', 'j.Leverling_2@gmail.com', 'Janet_Leverling@hotmail.com')
,('Peacock Margaret', 'Peacock@gmail.com', 'Peacock_12@gmail.com', 'Margaret_Peacock@hotmail.com')
GO

SELECT * FROM Employees;
GO
--OUTPUT

Example 1: Concatenate multiple columns & applied semi-colon (;) as a delimiter in between:

  • Old approach using add (+) operator:

In the old approach, when we need to concatenate two or more than two columns using Add (+) operator, we need to manually take care of the concatenation and add delimiter (separator) between columns as shown in the example. This approach was used earlier than SQL Server 2017.

USE TEST_DB
GO

SELECT [EmployeeName]
    , ([PrimaryEmail]+';'+[SecondaryEmail]+';'+[AlternateEmail]) AS [AllEmails]
FROM [Employees];
GO
--OUTPUT

  • New approach using CONCAT_WS() function:

In the new approach, we just need to use CONCAT_WS() function and it will take care of everything as shown below. It also reduces the complexity of the query since we need to apply delimiter once and the function repeats it automatically, as shown below.

Example 2: Concatenate multiple columns & applied space as a delimiter in between:

  • Old approach using add (+) operator:

In this example, we need to use add (+) operator and apply space as a delimiter multiple times in between the columns as shown below.

  • New Approach using CONCAT_WS() funcation :

In this example, we just need to use CONCAT_WS() function with space delimiter at once and it will be applied automatically after each column by the function itself.

Conclusion:

I found CONCAT_WS() function very much useful when concatenating multiple columns / expressions with delimiter. Let me know if you use this function and how did you find it.

Read Full Post »

Sometimes, we need to concatenate multiple fields to make a consolidated field. These fields may have same data type or multiple data types as well. In the past, we used multiple functions like ISNULL, CONVERT, CAST and used an Add (+) operator to concatenate it.

Now, we have a smart function called CONCAT() to achieve above mentioned scenario easily. This function is intelligent enough that to combine data of single / multiple data types. It converts all the data types to string before joining them together.

Let me show you some examples using old / new approaches.

Example 1: Concatenate multiple columns having NULL values

  • Old Approach Using Add (+) Operator

In old approach, we simply apply add(+) operator to combine multiple fields as shown below.

USE Northwind
GO

SELECT [CompanyName]
     , [Address]
	 , [City]
	 , [Region]
	 , [Address] + ' ' + [City] + ' ' + [Region] AS [FullAddress]
FROM [dbo].[Suppliers];
GO
--OUTPUT

As you can see above, if one of the columns is having NULL value, which you are trying to concatenate, then result will be NULL regardless of which field has value or not.

To resolve NULL issue, we need to use ISNULL function to replace NULL values with empty space and ISNULL should be applied to all columns which we are trying to concatenate, since most of the time, we may not know which column may have NULL values, as shown below.

USE Northwind
GO

SELECT [CompanyName]
     , [Address]
	 , [City]
	 , [Region]
	 , ISNULL([Address],'') + ' ' + ISNULL([City],'') + ' ' + ISNULL([Region],'') AS [FullAddress]
FROM [dbo].[Suppliers];
GO
--OUTPUT

  • New Approach Using CONCAT() Function :

Now, we have seen in earlier approach that how much effort required to concatenate fields. In the new approach, we just need to use a single function which is called CONCAT() function. This function allows us to concatenate multiple columns (varchar, int, datetime etc.) easily as shown in the example below.

USE Northwind
GO

SELECT [CompanyName]
     , [Address]
	 , [City]
	 , [Region]
	 , CONCAT([Address],' ',[City],' ',[Region]) AS [FullAddress]
FROM [dbo].[Suppliers];
GO
--OUTPUT

Example 2: Concatenate multiple columns having different data types

  • Old Approach Using Add (+) Operator

Let’s concatenate multiple data types column using Add (+) operator as shown below but it generates the error since you cannot combine different data types of columns with Add (+) operator, how we were handling such cases earlier.

USE Northwind
GO

SELECT [SupplierID] 
     , [ContactName]
	 , [SupplierID] + ' ' + [ContactName] AS [SupplierID&Name]
FROM  [dbo].[Suppliers];
GO
--OUTPUT

In order to resolve this error, we need to use the CONVERT() function which will convert the int value to nvarchar datatype to make it same data type (string) for both columns and then concatenate it as shown below:

USE Northwind
GO

SELECT [SupplierID] 
     , [ContactName]
	 , CONVERT(NVARCHAR(50)
	 , [SupplierID]) + ' ' + [ContactName] AS [SupplierID&Name]
FROM   [dbo].[Suppliers];
GO
--OUTPUT

  • New Approach Using CONCAT() function:

As we can see many hurdles and complexity in the old approach, in new approcah we need to simply apply CONCAT() function where it itself converts all columns data type to string and then concatenate it and retrun string as an output, as described in below example.

USE Northwind
GO

SELECT [SupplierID] 
     , [ContactName]
	 , CONCAT([SupplierID],' ',[ContactName]) AS [SupplierId&Name]
FROM   [dbo].[Suppliers];
GO
--OUTPUT

Conclusion:

I used CONCAT() function multiple times and found out extremly useful since it automatically handles NULL cases, different data type cases etc. If you use this function, do let me know your experience.

Read Full Post »

Splitting string in SQL Server was always challenging, we need to create a complex user defined function, using multiple SQL Server built in functions in order to achieve it. I have written an article back in 2012 regarding this. In SQL Server 2016, splitting string became so easy, SQL Server introduced a function to split string namely STRING_SPLIT(), it requires the compatibility level to be at least 130.

Let me create a sample to demonstrate STRING_SPLIT() functionality. In given below sample, I have multiple email addresses separated by a semicolon delimiter against each employee as shown below.

Sample :

USE tempdb
GO
  
CREATE TABLE #Employee
(
 EmployeeID     INT IDENTITY(1,1),
 EmployeeName   VARCHAR(100),
 EmailAddresses VARCHAR(500)
);
GO
  
INSERT INTO #Employee(EmployeeName, EmailAddresses)
VALUES
('John', 'John_1@gmail.com;John_2@gmail.com;John_3@hotmail.com'),
('Sarah', 'Sarah_1@gmail.com;Sarah_2@hotmail.com;Sarah_1@gmail.com'),
('Aaron', 'aaron_1@gmail@com;aaron_2@hotmail.com'),
('Ackerman', 'ackerman_1@gmail.com;ackerman_2@hotmail.com');
GO
  
SELECT * FROM #Employee
GO
--OUTPUT

Now sample is ready, let’s apply STRING_SPLIT() function to see how it works and how easy it is to implement it.

Example 1:

Given below is an example where I used sample created above and split email addresses based on delimiter using STRING_SPLIT() function.

USE tempdb
GO
   
SELECT EmployeeID
     , EmployeeName
     , value AS EmailAddress 
FROM  #Employee
CROSS APPLY 
STRING_SPLIT(EmailAddresses,';')
GO
--OUTPUT

In above records, we have successfully split email addresses and now we have one email address per row. In the above records, though we have successfully split email addresses, still we have duplicate email (Sarah_1@gmail.com) in email address column.

Let’s fix duplicate issue in below example.

Example 2: Removal of duplicate data

In order to remove duplicate email address, we need to use GROUP BY function along with STRING_SPLIT() function in the given below example.

USE tempdb
GO
  
SELECT EmployeeID
     , EmployeeName
     , value AS EmailAddress
FROM  #Employee
CROSS APPLY STRING_SPLIT(EmailAddresses,';')
GROUP BY EmployeeID 
       , EmployeeName
       , value;
GO
--OUTPUT

As you can see above, duplication in email address column has been removed.

Conclusion:

I found STRING_SPLIT() function very useful and we can easily split string without even writing a lot of scripts. You can also implement it wherever it is required without any complexity. Do let me know if you face any issues.

Read Full Post »

SQL Server 2022 brought some exiting features which will help us in optimising the SQL scripts. Window clause is one of the new features. Also, it helps us to reduce the code complexity when we deal with multiple OVER Clause.

  • Old Approach (Earlier than SQL Server 2022):
  • As we can see in the below example that in the OVER Clause, we defined same Partition By & Order By, over and over again, since there was no Window clause available in the earlier edition of SQL Server.

    USE Northwind
    GO
    
    SELECT [OrderID]
         , [ProductID]
    	 , ROW_NUMBER()     OVER (PARTITION BY [ProductID] 
    	                          ORDER BY     [ProductID]) AS [RowNo]
    	 , [UnitPrice]
    	 , [Quantity]
         , AVG([UnitPrice]) OVER (PARTITION BY [ProductID] 
    	                          ORDER BY     [ProductID]) AS [AverageUnitPricePerProduct]
    	 , SUM([Quantity])  OVER (PARTITION BY [ProductID] 
    	                          ORDER BY     [ProductID]) AS [TotalQuantityPerProduct]
    FROM   [dbo].[Order Details]
    WHERE  [ProductID] IN (9,15);
    GO
    --OUTPUT
    

  • New Approach (SQL Server 2022 & Above):
  • Compatibility Level:

    Your database compatibility level MUST be 160 or higher to use Window clause. Given below is the script to change the database compatibility level.

     ALTER DATABASE Northwind SET COMPATIBILITY_LEVEL = 160 

    In the new approach, you can simply define a Window clause just one time and use it over and over again in your query as shown below. It gives us the same result as mentioned above but with less complexity.

    USE Northwind
    GO
    
    SELECT [OrderID]
         , [ProductID]
    	 , ROW_NUMBER()     OVER Window1 AS [RowNo]
    	 , [UnitPrice]
    	 , [Quantity]
         , AVG([UnitPrice]) OVER Window1 AS [AverageUnitPricePerProduct]
    	 , SUM([Quantity])  OVER Window1 AS [TotalQuantityPerProduct]
    FROM [dbo].[Order Details]
    WHERE [ProductID] IN (9,15)
    WINDOW Window1 AS (PARTITION BY [ProductID] 
                       ORDER BY     [ProductID]);
    GO
    --OUTPUT
    

    Conclusion:

    The Window clause is very handy when we have the same Window clause used by multiple aggregate functions. It also reduces the complexity. Do let me know if you used Window clause and found it useful or not.

    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 »

    All of us know that user defined functions may affect the query performance very badly, specially when we are dealing with a huge amount of data. Despite saying this, most of the time we are left with no choice but to use User Defined Function (UDF) and bear the cost of its performance.

    In SQL Server 2019, a feature shipped namely Scalar UDF Inlining, which was a long awaited feature. The main goal of this feature is to improve the performance of UDF drastically. Excited ?

    Let me create a sample User Defined Function (UDF) to use in my demonstration as shown below.

    Sample:

    USE WideWorldImporters;
    GO
    
    CREATE FUNCTION [dbo].[UDF_customer_Name]
    (
     @CustomerID INT
    )
    RETURNS VARCHAR(250) 
    AS
    BEGIN
    
      DECLARE @CustomerName VARCHAR(250);
    
      SELECT  @CustomerName  = [CustomerName] 
      FROM    [Sales].[Customers] 
      WHERE  [CustomerID] = @CustomerID;
    
      RETURN  @CustomerName;
    END
    GO
    

    Let me show you in the below example how we were using UDF in the earlier version of SQL Server and facing performance issues. Let me call the above created UDF in the below query and show you its performance. In this UDF, I will pass the Customer ID as a parameter and get Customer Name in return.

    USE WideWorldImporters;
    GO
    
    SET STATISTICS TIME ON; 
    GO
    
    SELECT [CustomerID]
         , [dbo].[UDF_Customer_Name](CustomerID) AS [CustomerName]
         , [InvoiceID]
         , [TransactionDate]
    FROM   [Sales].[CustomerTransactions];
    GO
    
    SET STATISTICS TIME OFF; 
    GO
    --OUTPUT
    

    Performance:

    As we can see below, I have 97147 records and it takes 5 seconds to execute the query as shown below.

    Scalar UDF Inlining Feature:

    As we can see in above example, it took time to execute above query even though we have few records, which means that the performance is not good and this was normal. Now let’s try Scalar UDF Inlining feature to see the performance impact.

    Compatibility level:

    The database compatibility MUST be 150 or higher to use this feature. Given below is the query to set the compatibility level.

    ALTER DATABASE WideWorldImporters
    SET COMPATIBILITY_LEVEL =150;
    GO
    --OUTPUT
    

    Step 1:

    Let’s enable Scalar UDF Inlining as shown below.

    USE WideWorldImporters;
    GO
    
    ALTER DATABASE SCOPED CONFIGURATION 
    SET TSQL_SCALAR_UDF_INLINING = ON;
    GO
    

    Step 2:

    Let’s check the inlineable status of my above created UDF by using sys.sql_modules. It MUST be 1 to use this feature as shown below.

    USE WideWorldImporters;
    GO
    
    SELECT object_id
         , definition
         , is_inlineable
    FROM sys.sql_modules
    WHERE definition LIKE '%UDF_CUSTOMER%';
    GO
    

    Step 3:

    Now, let’s execute the same query and check the performance as shown below

    USE WideWorldImporters;
    GO
    
    SET STATISTICS TIME ON; 
    GO
    
    SELECT [CustomerID]
         , [dbo].[UDF_Customer_Name](CustomerID) AS [CustomerName]
    	 , [InvoiceID]
    	 , [TransactionDate]
    FROM   [SALES].[CustomerTransactions];
    GO
    --Output
    SET STATISTICS TIME OFF; 
    GO
    

    Performance:

    As we can see below that this feature has increased the performance tremendously and it hardly took 1 second to execute the query.

    Clean Up:

    Let’s drop the above created User Defined Function.

    USE WideWorldImporters;
    GO
    
    DROP FUNCTION [dbo].[UDF_customer_Name]
    GO
    

    Limitations:

    There are certain limitations for this feature, if those conditions are NOT met in your user defined function, then you can’t use this feature, please review it here.

    Conclusion:

    I found this new feature very useful since it improves the performance of User Defined Function a lot. Do let me know if you use this feature and how helpful you find it.

    Read Full Post »

    We all have been using RTRIM() function for ages, it helps us to removes the unwanted space(s) character char(32) from the end of any column(s) \ expression(s) in earlier version of SQL Server.

    In SQL Server 2022, an enhancement came in RTRIM() function, which was a long awaited functionality. This enhancement will allow us to remove any specific character(s) from the RIGHT sides along with space(s) character char(32).

    Let me show you in the below example, how we were using RTRIM() functions to remove space(s) character char(32) ONLY in the earlier version of SQL Server.

    Example 1:

    DECLARE @EMAIL VARCHAR(100) 
    SET @EMAIL = 'KenSanchez@gmail.com   ';
    SELECT  @EMAIL   AS [OriginalEmail]
    , RTRIM(@EMAIL)  AS [RTrimEmail];
    GO
    --OUTPUT
    

    Enhancement:

    Now, let me demonstrate this enhancement by giving few examples but before demonstrating this enhancement, your database compatibility level MUST be 160 or higher. Given below is the query to change your database compatibility level.

     ALTER DATABASE AdventureWorks SET COMPATIBILITY_LEVEL = 160 

    Example 2:

    In this example, I will show you how to pass the newly introduced parameter in RTRIM() function. This parameter removes spaces(s) / character(s) from the RIGHT side of the column(s) / expression(s) which will be defined in single quotes after RTRIM() as shown below.

    DECLARE @EMAIL VARCHAR(100) 
    SET @EMAIL = 'KenSanchez@gmail.com;';
    SELECT  @EMAIL       AS [OriginalEmail]
    , RTRIM(@EMAIL,'; ')  AS [RTrimEmail];
    GO
    --OUTPUT
    

    Example 3:

    In this example, I will demonstrate that by default RTRIM() function takes spaces(s) as parameter, if you do not pass any parameter as shown in below example :

    DECLARE @EMAIL VARCHAR(100) 
    SET @EMAIL = '     KenSanchez@gmail.com';
    SELECT  @EMAIL   AS [OriginalEmail]
    , RTRIM(@EMAIL)  AS [RTrimEmail]
    , RTRIM(@EMAIL,' ') AS [RTrimEmailWithParameter];
    GO
    --OUTPUT
    

    Conclusion:

    I found the new enhancement of RTRIM() function very useful, earlier we used multiple functions to find and remove any character(s) from the RIGHT side of the column(s) \ expression(s) but now we can easily achieve with the help of RTRIM() function. Do let me know if you use this function and how you find it.

    Read Full Post »

    We all have been using LTRIM() function for ages, it helps us to removes the unwanted space(s) character char(32) from the start of any column(s) \ expression(s) in earlier version of SQL Server.

    In SQL Server 2022, an enhancement came in LTRIM() function, which was a long awaited functionality. This enhancement will allow us to remove any specific character(s) from the left sides along with space(s) character char(32).

    Let me show you in the below example, how we were using LTRIM() functions to remove space(s) character char(32) ONLY in the earlier version of SQL Server.

    Example 1:

    DECLARE @EMAIL VARCHAR(100) 
    SET @EMAIL = '     KenSanchez@gmail.com';
    SELECT  @EMAIL   AS [OriginalEmail]
    , LTRIM(@EMAIL)  AS [LTrimEmail];
    GO
    --OUTPUT
    

    Enhancement:

    Now, let me demonstrate this enhancement by giving few examples but before demonstrating this enhancement, your database compatibility level MUST be 160 or higher. Given below is the query to change your database compatibility level.

     ALTER DATABASE AdventureWorks SET COMPATIBILITY_LEVEL = 160 

    Example 2:

    In this example, I will show you how to pass the newly introduced parameter in LTRIM() function. This parameter removes spaces(s) / character(s) from the LEFT side of the column(s) / expression(s) which will be defined in single quotes after LTRIM() as shown below.

    DECLARE @EMAIL VARCHAR(100) 
    SET @EMAIL = '     ;KenSanchez@gmail.com';
    SELECT  @EMAIL       AS [OriginalEmail]
    , LTRIM(@EMAIL,'; ')  AS [LTrimEmail];
    GO
    --OUTPUT
    

    Example 3:

    In this example, I will demonstrate that by default LTRIM() function takes spaces(s) as parameter, if you do not pass any parameter as shown in below example:

    DECLARE @EMAIL VARCHAR(100) 
    SET @EMAIL = '     KenSanchez@gmail.com';
    SELECT  @EMAIL   AS [OriginalEmail]
    , LTRIM(@EMAIL)  AS [LTrimEmail]
    , LTRIM(@EMAIL,' ') AS [LTrimEmailWithParameter];
    GO
    --OUTPUT
    

    Conclusion:

    I found the new enhancement of LTRIM() function very useful, earlier we used multiple functions to find and remove any character(s) from the LEFT side of the column(s) \ expression(s) but now we can easily achieve with the help of LTRIM() function. Do let me know if you use this function and how you find it.

    Read Full Post »

    Older Posts »