SQL Server-6 - Built-In Functions
SQL Server-6 - Built-In Functions
ASCII(Character_Expression)
The ASCII function returns the ASCII code that represents a specific character.
To find the ASCII Code of the capital letter ‘A’
Example: Select ASCII(‘A’)
Output: 65
This function is commonly used for comparing characters without knowing whether they are
in the upper case or lower case. Uppercase and lower case letters translate into different
ASCII values
CHAR(Integer_Expression)
This function converts an integer ASCII code to a character. That means the CHAR function
does the opposite of the ASCII function. The Integer_Expression should be between 0 and
255.
SET @Number = 65
WHILE(@Number <= 90)
BEGIN
PRINT CHAR(@Number)
END
Note: The while loop will become an infinite loop if you forget to include the following line.
Set @Number = @Number + 1
SET @Number = 97
BEGIN
PRINT CHAR(@Number)
END
Another way of printing lower case alphabets using CHAR() and LOWER()
functions.
DECLARE @Number int
SET @Number = 65
BEGIN
PRINT LOWER(CHAR(@Number))
END
LTRIM(Character_Expression)
This function returns a character expression after it removes the leading blanks. That
means it removes blanks on the left-hand side of the given character expression.
Example: Removing the 3 white spaces on the left-hand side of the ‘ Hello’ string using
LTRIM() function.
Select LTRIM(‘ Hello’)
Output: Hello
RTRIM(Character_Expression)
This function returns a character string after truncating all trailing blanks. That means it
removes blanks on the right-hand side of the given character expression.
Example: Removing the 3 white spaces on the left-hand side of the ‘Hello ‘ string using
RTRIM() function.
Select RTRIM(‘Hello ‘)
Output: Hello
If you want to remove white spaces on either side of the given character expression, then
you need to use LTRIM() and RTRIM() as shown below.
Select LTRIM(RTRIM(‘ Hello ‘))
Output: Hello
LOWER(Character_Expression)
This function returns a character expression after converting all the uppercase character
data to lowercase. That means it converts all the characters in the given
Character_Expression to lowercase letters.
Example: Select LOWER(‘CONVERT This String Into Lower Case’)
Output: convert this string into lower case
UPPER(Character_Expression)
This function returns a character expression with lowercase character data converted to
uppercase. That means it converts all the characters in the given Character_Expression to
uppercase letters.
Example: Select UPPER(‘CONVERT This String Into upperCase’)
Output: CONVERT THIS STRING INTO UPPERCASE
REVERSE(‘Any_String_Expression’)
This function returns the reverse of a character expression. That means it reverses all the
characters in the given string expression.
Example: Select REVERSE(‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’)
Output: ZYXWVUTSRQPONMLKJIHGFEDCBA
LEN(String_Expression)
This function returns the number of characters, instead of the number of bytes, of the
specified string expression, excluding trailing blanks. That means it returns the count of total
characters in the given string expression, excluding the blanks at the end of the expression.
Example: Select LEN(‘ Functions ‘)
Output: 10
LEFT(Character_Expression, Integer_Expression)
This function returns the left part of a character string with the specified number of
characters. That means it returns the specified number of characters from the left-hand side
of the given character expression.
Example: Select LEFT(‘ABCDE’, 3)
Output: ABC
RIGHT(Character_Expression, Integer_Expression)
This function returns the right part of a character string with the specified number of
characters. That means it returns the specified number of characters from the right-hand
side of the given character expression.
Example: Select RIGHT(‘ABCDE’, 3)
Output: CDE
Example: Display just the domain part of the given email ‘[email protected]’.
Select SUBSTRING(‘[email protected]’,6, 19)
Output: dotnettutorials.net
In the above example, we have hardcoded the starting position and the length parameters.
Instead of hard-coding, we can dynamically retrieve them using CHARINDEX() and LEN()
string functions as shown below.
Example:
Select SUBSTRING(‘[email protected]’,(CHARINDEX(‘@’,
‘[email protected]’) + 1),
(LEN(‘[email protected]’) – CHARINDEX(‘@’,’[email protected]’)))
Output: dotnettutorials.net
2.OVER Clause in SQL Server
The OVER clause in SQL Server is used with PARTITION BY to break up the data into
partitions. Following is the syntax of the OVER clause.
The specified function is going to operate for each partition. See the following example. Let
say we have three departments (HR, IT, Payroll).
COUNT (Department) OVER (PARTITION BY Department)
In the above example, the data will be partition by Department i.e. there will be three
partitions (IT, HR, and Payroll), and then the COUNT() function will be applied to each
partition. Here, you can use a wide range of built-in functions such as COUNT(), SUM(),
MAX(), ROW_NUMBER(), RANK(), DENSE_RANK(), AVG(), MIN(), etc.
Example: OVER clause in SQL Server
Let us see an example, to understand the use of the SQL Server Over clause. We are going
to use the following Employee table.
Example:
We need to generate a report to display the total number of employees department-wise.
Along with this we also need to display the Total Salary, Average Salary, Minimum Salary,
and Maximum Salary department wise. That means we need to generate a report like
below.
We can easily achieve the above data simply by using the GROUP BY clause in SQL
Server. The following SQL Query will give you the desired output.
SELECT Department,
COUNT(*) AS NoOfEmployees,
SUM(Salary) AS TotalSalary,
AVG(Salary) AS AvgSalary,
MIN(Salary) AS MinSalary,
MAX(Salary) AS MaxSalary
FROM Employees
GROUP BY Department
Example:
Now the business requirement changes, now we also need to show the non-aggregated
values (Name and Salary) in the report along with the aggregated values as shown in the
below image.
You may be intended to use the following SQL query by adding the Salary, Name column in
the select clause. But this is not going to be work.
SELECT Name, Salary, Department,
COUNT(*) AS NoOfEmployees,
SUM(Salary) AS TotalSalary,
AVG(Salary) AS AvgSalary,
MIN(Salary) AS MinSalary,
MAX(Salary) AS MaxSalary
FROM Employees
GROUP BY Department
When you execute the above query, you will get the following error. This is because it is not
possible to include the non-aggregated column in the select list when you are using a group
by clause in SQL Server.
How can we achieve the desired output?
We can get the desired output in two ways.
Solution1:
One of the ways to get the desired output is by including all the aggregations in a subquery
and then JOINING that subquery with the main query. The following example exactly does
the same.
SELECT Name, Salary, Employees.Department,
Departments.DepartmentTotals,
Departments.TotalSalary,
Departments.AvgSalary,
Departments.MinSalary,
Departments.MaxSalary
FROM Employees
INNER JOIN
SUM(Salary) AS TotalSalary,
AVG(Salary) AS AvgSalary,
MIN(Salary) AS MinSalary,
MAX(Salary) AS MaxSalary
FROM Employees
ON Departments.Department = Employees.Department
Once you execute the above query then you will get the desired output. But look at the
number of T-SQL statements that we wrote.
Solution2:
The second way that is the most preferable way to get the desired output is by using the
OVER clause combined with the PARTITION BY clause as shown in the below code.
SELECT Name,
Salary,
Department,
FROM Employees
Once you execute the above code, you will get the output as expected.
3.Row_Number Function
The Row Number function was introduced in SQL Server 2005. The ROW_NUMBER
function is basically used when you want to return a sequential number starting from 1.
The ROW_NUMBER() is a built-in function in SQL Server that assigns a sequential integer
number to each row within a partition of a result set. The row number always starts with 1
for the first row in each partition and then increases by 1 for the next row onwards in each
partition. The syntax to use the ROW_NUMBER function is given below.
PARTITION BY value_expression:
This is optional. The PARTITION BY clause is used to divide the result set that is produced
by the FROM clause into partitions and then the ROW_NUMBER function is applied to each
partition. Here, the value_expression specifies the column name (s) using which the result
set is going to be partitioned. As it is optional, if you did not specify the PARTITION BY
clause, then the ROW_NUMBER function will treat all the rows of the query as a single
group.
Order_by_clause:
It is required. The ORDER BY clause is basically used to define the sequence in which
each row is going to assign its unique ROW_NUMBER.
Note: If you did not use the PARTITION BY clause with the ROW_NUMBER function, then
the result set will consider as a single partition.
Once you execute the above query, you will get the below output. As you can see in the
below output, there will be no partition and hence all the rows are assigned with consecutive
sequence numbering starting from 1 to 12.
Note: If you did not specify the ORDER BY clause then you will get the error stating “The
function ‘ROW_NUMBER’ must have an OVER clause with ORDER BY”.
ROW_NUMBER() OVER
PARTITION BY Department
ORDER BY Name
) AS RowNumber
FROM Employees
Note: When the partition changes the row number is reset to 1. So, basically whenever you
want to give a unique number on the fly to the rows in the result set, then you need to use
the ROW_NUMBER function.
Real-time Example of ROW_NUMBER function in SQL Server:
Let us see one real-time example of the ROW_NUMER function in SQL Server. To
understand this first delete all the records which are there in the Employees table by
executing the following SQL query.
TRUNCATE TABLE Employees
Once you delete all the data from the Employees table then please insert the following
records into the Employees table.
INSERT INTO Employees Values (1, 'James', 'IT', 15000)
The following SQL query will delete the duplicate records from the Employees table. Here,
the PARTITION BY clause divides the query result set into partitions based on the ID
values. That means it will create multiple partitions based on the ID values and give
sequential integer numbers starting from 1 for each partition. Then here the DELETE
statements will delete the records from each partition where the RowNumber is greater than
1. It means it will keep only one record from each partition and delete the rest of all.
WITH DeleteDuplicateCTE AS
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) AS
RowNumber
FROM Employees
)
DELETE FROM DeleteDuplicateCTE WHERE RowNumber > 1
Once you execute the above SQL query, now verify the Employees table and you can see
the duplicates records are deleted. So, in short, the ROW_NUMBER function Returns an
increasing unique number for each row starting from 1, even if there are duplicates.
Both the RANK and DENSE_RANK functions were introduced in SQL Server 2005. Again
both these functions are used to return sequential numbers starting from 1 based on the
ordering of rows imposed by the ORDER BY clause. Let us first understand these functions
in detail with some examples and then we will try to understand the difference between
them.
Note: When you have two records with the same data, then it will give the same rank to
both the rows.
Once you execute the above query, you will get the following output. As you can see in the
below output, there will be no partition and hence all the rows are assigned with consecutive
sequences starting from 1 except when there is a tie i.e. when the salary is 8000 and
65000, it gives the same rank to both the rows.
The Rank function in SQL Server skips the ranking(s) when there is a tie. As you can see in
the above output, Ranks 2 and 6 are skipped as there are 2 rows at rank 1 as well as 2
rows at rank 5. The third row gets rank 3 and the 7th row gets rank 7.
Now execute the following code and you will get the output as we discussed in the previous
image.
So, in short, The RANK function Returns an increasing unique number for each row starting
from 1 and for each partition. When there are duplicates, the same rank is assigned to all
the duplicate rows, but the next row after the duplicate rows will have the rank it would have
been assigned if there had been no duplicates. So the RANK function skips rankings if there
are duplicates.
The PARTITION BY clause is optional and it is used to partition the result set into multiple
groups. If you did not specify the PARTITION BY clause, then the DENSE_RANK function
will treat the entire result set as a single partition. The ORDER BY clause is mandatory and
it is used to define the sequence in which each row is going to assign with their
DENSE_RANK i.e. number. Let us understand how to use the DENSE_RANK function in
SQL Server with some examples.
When you execute the above SQL Query, it will give you the following output. As you can
see in the output, there will be no partition and hence all the rows are assigned with
consecutive sequences starting from 1 except when there is a tie i.e. when the salary is
8000 and 65000, it gives the same rank to both the rows.
Unlike the Rank function, the DENSE_RANK function will not skip the ranking(s) when there
is a tie. As you can see in the above output, we have two rows with rank 1 and the next
immediate row rank is 3 and this is the only difference between RANK and DENSE_RANK
function in SQL Server.
Let us see an example of the DENSE_RANK function in SQL Server using the PARTITION
BY Clause. Like the RANK function, it will also partition the result set based on the column
that you specify in the PARTITION BY Clause. In order to understand this better, please
have a look at the following diagram. As you can see we have specified the Department
column in the Partition By clause and Salary column in the Order By clause.
As we have two departments i.e. IT and HR, so, the Partition By Clause will divide all the
data into two partitions. One partition is going to hold the IT department employees while
the other partition is going to hold the HR department employees. Then in each partition,
the records are sorted based on the Salary column. The DENSE_RANK function is then
applied on each record in each partition and provides sequence numbers starting from 1
except when there is a tie. In the case of a tie, it gives the same rank without skipping the
ranking.
Now execute the below SQL Script and you should get the output as we discussed in the
previous image.
WITH EmployeeCTE AS
FROM Employees
WITH EmployeeCTE AS
(
SELECT Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) AS
DenseRank_Salry
FROM Employees
AS Salary_Rank
FROM Employees
So, in short, the DENSE_RANK function returns an increasing unique number for each row
starting from 1 and for each partition. When there are duplicates, then the same rank is
assigned to all the duplicate rows but it will not skip any ranks. This means the next row
after the duplicate rows will have the next rank in the sequence.