Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
3 views

SQL Notes

The document provides detailed SQL instructions on creating unique indexes, rebuilding indexes, and using row numbers for data manipulation. It also explains the differences between GROUP BY and DISTINCT, as well as various string functions available in SQL. Additionally, it covers conditional aggregation and list concatenation techniques for summarizing data.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

SQL Notes

The document provides detailed SQL instructions on creating unique indexes, rebuilding indexes, and using row numbers for data manipulation. It also explains the differences between GROUP BY and DISTINCT, as well as various string functions available in SQL. Additionally, it covers conditional aggregation and list concatenation techniques for summarizing data.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

fail. (Tables with no clustered indexes are also called heaps.

CREATE UNIQUE INDEX uq_customers_email ON Customers(Email);

This will create an unique index for the column Email in the table Customers. This index, along with speeding up
queries like a normal index, will also force every email address in that column to be unique. If a row is inserted or
updated with a non-unique Email value, the insertion or update will, by default, fail.

CREATE UNIQUE INDEX ix_eid_desc ON Customers(EmployeeID);

This creates an index on Customers which also creates a table constraint that the EmployeeID must be unique.
(This will fail if the column is not currently unique - in this case, if there are employees who share an ID.)

CREATE INDEX ix_eid_desc ON Customers(EmployeeID Desc);

This creates an index that is sorted in descending order. By default, indexes (in MSSQL server, at least) are
ascending, but that can be changed.

Section 37.6: Rebuild index


Over the course of time B-Tree indexes may become fragmented because of updating/deleting/inserting data. In
SQLServer terminology we can have internal (index page which is half empty ) and external (logical page order
doesn't correspond physical order). Rebuilding index is very similar to dropping and re-creating it.

We can re-build an index with

ALTER INDEX index_name REBUILD;

By default rebuilding index is offline operation which locks the table and prevents DML against it , but many RDBM
allow online rebuilding. Also, some DB vendors offer alternatives to index rebuilding such as
REORGANIZE
(SQLServer) orCOALESCE/ SHRINK SPACE(Oracle).

Section 37.7: Inserting with a Unique Index


UPDATE Customers SET Email = "richard0123@example.com" WHERE id = 1;

This will fail if an unique index is set on the Email column of Customers. However, alternate behavior can be defin
for this case:

UPDATE Customers SET Email = "richard0123@example.com" WHERE id = 1 ON DUPLICATE KEY;

GoalKicker.com – SQL Notes for Professionals 104


Chapter 38: Row number
Section 38.1: Delete All But Last Record (1 to Many Tabl
WITH cte AS (
SELECT ProjectID,
ROW_NUMBER() OVER (PARTITION BY ProjectID ORDER BY InsertDate DESC) AS rn
FROM ProjectNotes
)
DELETE FROM cte WHERE rn > 1;

Section 38.2: Row numbers without partitions


Include a row number according to the order specified.

SELECT
ROW_NUMBER() OVER(ORDER BY Fname ASC) AS RowNumber,
Fname,
LName
FROM Employees

Section 38.3: Row numbers with partitions


Uses a partition criteria to group the row numbering according to it.

SELECT
ROW_NUMBER() OVER(PARTITION BY DepartmentId ORDER BY DepartmentId ASC) AS RowNumber,
DepartmentId, Fname, LName
FROM Employees

GoalKicker.com – SQL Notes for Professionals 105


Chapter 39: SQL Group By vs Distinct
Section 39.1: Dierence between GROUP BY and DISTINC
GROUP BYis used in combination with aggregation functions. Consider the following table:

orderId userId storeName orderValue orderDate


1 43 Store A 25 20-03-2016
2 57 Store B 50 22-03-2016
3 43 Store A 30 25-03-2016
4 82 Store C 10 26-03-2016
5 21 Store A 45 29-03-2016

The query below usesGROUP BYto perform aggregated calculations.

SELECT
storeName,
COUNT(*) AS total_nr_orders,
COUNT(DISTINCT userId) AS nr_unique_customers,
AVG(orderValue) AS average_order_value,
MIN(orderDate) AS first_order,
MAX(orderDate) AS lastOrder
FROM
orders
GROUP BY
storeName;

and will return the following information

storeName total_nr_orders nr_unique_customers average_order_value first_order lastOrder


Store A 3 2 33.3 20-03-2016 29-03-2016
Store B 1 1 50 22-03-2016 22-03-2016
Store C 1 1 10 26-03-2016 26-03-2016

While DISTINCT is used to list a unique combination of distinct values for the specified columns.

SELECT DISTINCT
storeName,
userId
FROM
orders;
storeName userId
Store A 43
Store B 57
Store C 82
Store A 21

GoalKicker.com – SQL Notes for Professionals 106


Chapter 40: Finding Duplicates on a
Column Subset with Detail
Section 40.1: Students with same name and date of birt
WITH CTE (StudentId, Fname, LName, DOB, RowCnt)
as (
SELECT StudentId, FirstName, LastName, DateOfBirth as DOB, SUM(1) OVER (Partition By FirstName,
LastName, DateOfBirth) as RowCnt
FROM tblStudent
)
SELECT * from CTE where RowCnt > 1
ORDER BY DOB, LName

This example uses a Common Table Expression and a Window Function to show all duplicate rows (on a subset of
columns) side by side.

GoalKicker.com – SQL Notes for Professionals 107


Chapter 41: String Functions
String functions perform operations on string values and return either numeric or string values.

Using string functions, you can, for example, combine data, extract a substring, compare strings, or convert a stri
to all uppercase or lowercase characters.

Section 41.1: Concatenate


In (standard ANSI/ISO) SQL, the operator for string concatenation
|| .is
This syntax is supported by all major
databases except SQL Server:

SELECT 'Hello' || 'World' || '!'; --returns HelloWorld!

Many databases support CONCAT


a function to join strings:

SELECT CONCAT('Hello', 'World'); --returns 'HelloWorld'

Some databases support using


CONCATto join more than two strings (Oracle does not):

SELECT CONCAT('Hello', 'World', '!'); --returns 'HelloWorld!'

In some databases, non-string types must be cast or converted:

SELECT CONCAT('Foo', CAST(42 AS VARCHAR(5)), 'Bar'); --returns 'Foo42Bar'

Some databases (e.g., Oracle) perform implicit lossless conversions. For example, a on a CLOBand NCLOB
CONCAT
yields aNCLOB. A CONCATon a number and avarchar2 results in avarchar2 , etc.:

SELECT CONCAT(CONCAT('Foo', 42), 'Bar') FROM dual; --returns Foo42Bar

Some databases can use the non-standard


+ operator (but in most,
+ works only for numbers):

SELECT 'Foo' + CAST(42 AS VARCHAR(5)) + 'Bar';

On SQL Server < 2012, where


CONCATis not supported,+ is the only way to join strings.

Section 41.2: Length


SQL Server

The LEN doesn't count the trailing space.

SELECT LEN('Hello') -- returns 5

SELECT LEN('Hello '); -- returns 5

The DATALENGTH counts the trailing space.

SELECT DATALENGTH('Hello') -- returns 5

SELECT DATALENGTH('Hello '); -- returns 6

GoalKicker.com – SQL Notes for Professionals 108


It should be noted though, that DATALENGTH returns the length of the underlying byte representation of the strin
which depends, i.a., on the charset used to store the string.

DECLARE @str varchar(100) = 'Hello ' --varchar is usually an ASCII string, occupying 1 byte per
char
SELECT DATALENGTH(@str) -- returns 6

DECLARE @nstr nvarchar(100) = 'Hello ' --nvarchar is a unicode string, occupying 2 bytes per char
SELECT DATALENGTH(@nstr) -- returns 12

Oracle

Syntax: Length ( char )

Examples:

SELECT Length('Bible') FROM dual; --Returns 5


SELECT Length('righteousness') FROM dual; --Returns 13
SELECT Length(NULL) FROM dual; --Returns NULL

See Also: LengthB, LengthC, Length2, Length4

Section 41.3: Trim empty spaces


Trim is used to remove write-space at the beginning or end of selection

In MSSQL there is no single


TRIM()

SELECT LTRIM(' Hello ') --returns 'Hello '


SELECT RTRIM(' Hello ') --returns ' Hello'
SELECT LTRIM(RTRIM(' Hello ')) --returns 'Hello'

MySql and Oracle

SELECT TRIM(' Hello ') --returns 'Hello'

Section 41.4: Upper & lower case


SELECT UPPER('HelloWorld') --returns 'HELLOWORLD'
SELECT LOWER('HelloWorld') --returns 'helloworld'

Section 41.5: Split


Splits a string expression using a character separator. Note STRING_SPLIT()
that is a table-valued function.

SELECT value FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ');

Result:

value
-----
Lorem
ipsum
dolor
sit

GoalKicker.com – SQL Notes for Professionals 109


amet.

Section 41.6: Replace


Syntax:

REPLACE( String to search


, String to search for and replace
, String to place into the original string
)

Example:

SELECT REPLACE( 'Peter Steve Tom', 'Steve', 'Billy' ) --Return Values: Peter Billy Tom

Section 41.7: REGEXP


MySQL Version ≥ 3.19

Checks if a string matches a regular expression (defined by another string).

SELECT 'bedded' REGEXP '[a-f]' -- returns True

SELECT 'beam' REGEXP '[a-f]' -- returns False

Section 41.8: Substring


Syntax is:SUBSTRING ( string_expression, start, length ) . Note that SQL strings are 1-indexed.

SELECT SUBSTRING('Hello', 1, 2) --returns 'He'


SELECT SUBSTRING('Hello', 3, 3) --returns 'llo'

This is often used in conjunction with the


LEN() function to get the last
n characters of a string of unknown length.

DECLARE @str1 VARCHAR(10) = 'Hello', @str2 VARCHAR(10) = 'FooBarBaz';


SELECT SUBSTRING(@str1, LEN(@str1) - 2, 3) --returns 'llo'
SELECT SUBSTRING(@str2, LEN(@str2) - 2, 3) --returns 'Baz'

Section 41.9: Stu


Stuff a string into another, replacing 0 or more characters at a certain position.

Note: start position is 1-indexed (you start indexing at 1, not 0).

Syntax:

STUFF ( character_expression , start , length , replaceWith_expression )

Example:

SELECT STUFF('FooBarBaz', 4, 3, 'Hello') --returns 'FooHelloBaz'

Section 41.10: LEFT - RIGHT


Syntax is:
LEFT ( string-expression , integer )

GoalKicker.com – SQL Notes for Professionals 110


RIGHT ( string-expression , integer )

SELECT LEFT('Hello',2) --return He


SELECT RIGHT('Hello',2) --return lo

Oracle SQL doesn't have LEFT and RIGHT functions. They can be emulated with SUBSTR and LENGTH.
SUBSTR ( string-expression, 1, integer )
SUBSTR ( string-expression, length(string-expression)-integer+1, integer)

SELECT SUBSTR('Hello',1,2) --return He


SELECT SUBSTR('Hello',LENGTH('Hello')-2+1,2) --return lo

Section 41.11: REVERSE


Syntax is: REVERSE ( string-expression )

SELECT REVERSE('Hello') --returns olleH

Section 41.12: REPLICATE


The REPLICATE function concatenates a string with itself a specified number of times.

Syntax is: REPLICATE ( string-expression , integer )

SELECT REPLICATE ('Hello',4) --returns 'HelloHelloHelloHello'

Section 41.13: Replace function in sql Select and Update


The Replace function in SQL is used to update the content of a string. The function call is REPLACE( ) for MySQL,
Oracle, and SQL Server.

The syntax of the Replace function is:

REPLACE (str, find, repl)

The following example replaces occurrencesSouth


of with Southern in Employees table:

FirstName Address
James South New York
John South Boston
Michael South San Diego

Select Statement :

If we apply the following Replace function:

SELECT
FirstName,
REPLACE (Address, 'South', 'Southern') Address
FROM Employees
ORDER BY FirstName

Result:

GoalKicker.com – SQL Notes for Professionals 111


FirstName Address
James Southern New York
John Southern Boston
Michael Southern San Diego

Update Statement :

We can use a replace function to make permanent changes in our table through following approach.

Update Employees
Set city = (Address, 'South', 'Southern');

A more common approach is to use this in conjunction with a WHERE clause like this:

Update Employees
Set Address = (Address, 'South', 'Southern')
Where Address LIKE 'South%';

Section 41.14: INSTR


Return the index of the first occurrence of a substring (zero if not found)

Syntax: INSTR ( string, substring )

SELECT INSTR('FooBarBar', 'Bar') -- return 4


SELECT INSTR('FooBarBar', 'Xar') -- return 0

Section 41.15: PARSENAME


DATABASE : SQL Server

PARSENAME function returns the specific part of given string(object name). object name may contains string like
object name,owner name, database name and server name.

More details MSDN:PARSENAME

Syntax

PARSENAME('NameOfStringToParse',PartIndex)

Example

To get object name use part index


1

SELECT PARSENAME('ServerName.DatabaseName.SchemaName.ObjectName',1) // returns `ObjectName`


SELECT PARSENAME('[1012-1111].SchoolDatabase.school.Student',1) // returns `Student`

To get schema name use part index


2

SELECT PARSENAME('ServerName.DatabaseName.SchemaName.ObjectName',2) // returns `SchemaName`


SELECT PARSENAME('[1012-1111].SchoolDatabase.school.Student',2) // returns `school`

To get database name use part index


3

GoalKicker.com – SQL Notes for Professionals 112


SELECT PARSENAME('ServerName.DatabaseName.SchemaName.ObjectName',3) // returns `DatabaseName`
SELECT PARSENAME('[1012-1111].SchoolDatabase.school.Student',3) // returns `SchoolDatabase`

To get server name use part index


4

SELECT PARSENAME('ServerName.DatabaseName.SchemaName.ObjectName',4) // returns `ServerName`


SELECT PARSENAME('[1012-1111].SchoolDatabase.school.Student',4) // returns `[1012-1111]`

PARSENAME will returns null is specified part is not present in given object name string

GoalKicker.com – SQL Notes for Professionals 113


Chapter 42: Functions (Aggregate)
Section 42.1: Conditional aggregation
Payments Table

Customer Payment_type Amount


Peter Credit 100
Peter Credit 300
John Credit 1000
John Debit 500
select customer,
sum(case when payment_type = 'credit' then amount else 0 end) as credit,
sum(case when payment_type = 'debit' then amount else 0 end) as debit
from payments
group by customer

Result:

Customer Credit Debit


Peter 400 0
John 1000 500
select customer,
sum(case when payment_type = 'credit' then 1 else 0 end) as credit_transaction_count,
sum(case when payment_type = 'debit' then 1 else 0 end) as debit_transaction_count
from payments
group by customer

Result:

Customer credit_transaction_count debit_transaction_count


Peter 2 0
John 1 1

Section 42.2: List Concatenation


Partial credit to this SO answer.

List Concatenation aggregates a column or expression by combining the values into a single string for each group
string to delimit each value (either blank or a comma when omitted) and the order of the values in the result can
specified. While it is not part of the SQL standard, every major relational database vendor supports it in their own
way.

MySQL
SELECT ColumnA
, GROUP_CONCAT(ColumnB ORDER BY ColumnB SEPARATOR ',') AS ColumnBs
FROM TableName
GROUP BY ColumnA
ORDER BY ColumnA;

Oracle & DB2


SELECT ColumnA
, LISTAGG(ColumnB, ',') WITHIN GROUP (ORDER BY ColumnB) AS ColumnBs
FROM TableName

GoalKicker.com – SQL Notes for Professionals 114


GROUP BY ColumnA
ORDER BY ColumnA;

PostgreSQL
SELECT ColumnA
, STRING_AGG(ColumnB, ',' ORDER BY ColumnB) AS ColumnBs
FROM TableName
GROUP BY ColumnA
ORDER BY ColumnA;

SQL Server
SQL Server 2016 and earlier

(CTE included to encourage the DRY principle)

WITH CTE_TableName AS (
SELECT ColumnA, ColumnB
FROM TableName)
SELECT t0.ColumnA
, STUFF((
SELECT ',' + t1.ColumnB
FROM CTE_TableName t1
WHERE t1.ColumnA = t0.ColumnA
ORDER BY t1.ColumnB
FOR XML PATH('')), 1, 1, '') AS ColumnBs
FROM CTE_TableName t0
GROUP BY t0.ColumnA
ORDER BY ColumnA;

SQL Server 2017 and SQL Azure


SELECT ColumnA
, STRING_AGG(ColumnB, ',') WITHIN GROUP (ORDER BY ColumnB) AS ColumnBs
FROM TableName
GROUP BY ColumnA
ORDER BY ColumnA;

SQLite

without ordering:

SELECT ColumnA
, GROUP_CONCAT(ColumnB, ',') AS ColumnBs
FROM TableName
GROUP BY ColumnA
ORDER BY ColumnA;

ordering requires a subquery or CTE:

WITH CTE_TableName AS (
SELECT ColumnA, ColumnB
FROM TableName
ORDER BY ColumnA, ColumnB)
SELECT ColumnA
, GROUP_CONCAT(ColumnB, ',') AS ColumnBs
FROM CTE_TableName
GROUP BY ColumnA
ORDER BY ColumnA;

GoalKicker.com – SQL Notes for Professionals 115


Section 42.3: SUM
Sumfunction sum the value of all the rows in the group. If the group by clause is omitted then sums all the rows.

select sum(salary) TotalSalary


from employees;
TotalSalary
2500
select DepartmentId, sum(salary) TotalSalary
from employees
group by DepartmentId;
DepartmentId TotalSalary
1 2000
2 500

Section 42.4: AVG()


The aggregate function AVG() returns the average of a given expression, usually numeric values in a column.
Assume we have a table containing the yearly calculation of population in cities across the world. The records for
New York City look similar to the ones below:

EXAMPLE TABLE
city_name population year
New York City 8,550,405 2015
New York City ... ...
New York City 8,000,906 2005

To select the average population of the New York City, USA from a table containing city names, population
measurements, and measurement years for last ten years:

QUERY
select city_name, AVG(population) avg_population
from city_population
where city_name = 'NEW YORK CITY';

Notice how measurement year is absent from the query since population is being averaged over time.

RESULTS
city_name avg_population
New York City 8,250,754

Note: The AVG() function will convert values to numeric types. This is especially important to keep in mind
when working with dates.

Section 42.5: Count


You can count the number of rows:

SELECT count(*) TotalRows


FROM employees;
TotalRows

GoalKicker.com – SQL Notes for Professionals 116


4

Or count the employees per department:

SELECT DepartmentId, count(*) NumEmployees


FROM employees
GROUP BY DepartmentId;
DepartmentId NumEmployees
1 3
2 1

You can count over a column/expression with the effect that will not count thevalues:
NULL

SELECT count(ManagerId) mgr


FROM EMPLOYEES;
mgr
3

(There is one null value managerID column)

You can also use DISTINCT inside of another function such as COUNT to only find the DISTINCT members of the
set to perform the operation on.

For example:

SELECT COUNT(ContinentCode) AllCount


, COUNT(DISTINCT ContinentCode) SingleCount
FROM Countries;

Will return different values. The SingleCount will only Count individual Continents once, while the AllCount will
include duplicates.

ContinentCode
OC
EU
AS
NA
NA
AF
AF

AllCount: 7 SingleCount: 5

Section 42.6: Min


Find the smallest value of column:

select min(age) from employee;

Above example will return smallest value for column


age of employee table.

Syntax:

GoalKicker.com – SQL Notes for Professionals 117


SELECT MIN(column_name) FROM table_name;

Section 42.7: Max


Find the maximum value of column:

select max(age) from employee;

Above example will return largest value for column


age of employee table.

Syntax:

SELECT MAX(column_name) FROM table_name;

GoalKicker.com – SQL Notes for Professionals 118


Chapter 43: Functions (Scalar/Single Ro
SQL provides several built-in scalar functions. Each scalar function takes one value as input and returns one value
as output for each row in a result set.

You use scalar functions wherever an expression is allowed within a T-SQL statement.

Section 43.1: Date And Time


In SQL, you use date and time data types to store calendar information. These data types include the time, date,
smalldatetime, datetime, datetime2, and datetimeoffset. Each data type has a specific format.

Data type Format


time hh:mm:ss[.nnnnnnn]
date YYYY-MM-DD
smalldatetime YYYY-MM-DD hh:mm:ss
datetime YYYY-MM-DD hh:mm:ss[.nnn]
datetime2 YYYY-MM-DD hh:mm:ss[.nnnnnnn]
datetimeoffset YYYY-MM-DD hh:mm:ss[.nnnnnnn] [+/-]hh:mm

The DATENAMEfunction returns the name or value of a specific part of the date.

SELECT DATENAME (weekday,'2017-01-14') as Datename


Datename
Saturday

You use theGETDATEfunction to determine the current date and time of the computer running the current SQL
instance. This function doesn't include the time zone difference.

SELECT GETDATE() as Systemdate


Systemdate
2017-01-14 11:11:47.7230728

The DATEDIFF function returns the difference between two dates.

In the syntax, datepart is the parameter that specifies which part of the date you want to use to calculate
difference. The datepart can be year, month, week, day, hour, minute, second, or millisecond. You then specify th
start date in the startdate parameter and the end date in the enddate parameter for which you want to find the
difference.

SELECT SalesOrderID, DATEDIFF(day, OrderDate, ShipDate)


AS 'Processing time'
FROM Sales.SalesOrderHeader
SalesOrderID Processing time
43659 7
43660 7
43661 7
43662 7

The DATEADDfunction enables you to add an interval to part of a specific date.

GoalKicker.com – SQL Notes for Professionals 119


SELECT DATEADD (day, 20, '2017-01-14') AS Added20MoreDays
Added20MoreDays
2017-02-03 00:00:00.000

Section 43.2: Character modifications


Character modifying functions include converting characters to upper or lower case characters, converting
numbers to formatted numbers, performing character manipulation, etc.

The lower(char) function converts the given character parameter to be lower-cased characters.

SELECT customer_id, lower(customer_last_name) FROM customer;

would return the customer's last name changed from "SMITH" to "smith".

Section 43.3: Configuration and Conversion Function


An example of a configuration function in SQL is the function. This function provides the name of the
@@SERVERNAME
local server that's running SQL.

SELECT @@SERVERNAME AS 'Server'


Server
SQL064

In SQL, most data conversions occur implicitly, without any user intervention.

To perform any conversions that can't be completed implicitly, you can use theor CONVERTfunctions.
CAST

The CAST function syntax is simpler than the


CONVERTfunction syntax, but is limited in what it can do.

In here, we use both the


CAST and CONVERTfunctions to convert the datetime data type to varchar
the data type.

The CAST function always uses the default style setting. For example, it will represent dates and times using the
format YYYY-MM-DD.

The CONVERTfunction uses the date and time style you specify. In this case, 3 specifies the date format dd/mm/yy.

USE AdventureWorks2012
GO
SELECT FirstName + ' ' + LastName + ' was hired on ' +
CAST(HireDate AS varchar(20)) AS 'Cast',
FirstName + ' ' + LastName + ' was hired on ' +
CONVERT(varchar, HireDate, 3) AS 'Convert'
FROM Person.Person AS p
JOIN HumanResources.Employee AS e
ON p.BusinessEntityID = e.BusinessEntityID
GO
Cast Convert
David Hamiltion was hired on 2003-02-04 David Hamiltion was hired on 04/02/03

Another example of a conversion function is the


PARSE function. This function converts a string to a specified data
type.

In the syntax for the function, you specify the string that must be converted,
AS the
keyword, and then the required

GoalKicker.com – SQL Notes for Professionals 120


data type. Optionally, you can also specify the culture in which the string value should be formatted. If you don't
specify this, the language for the session is used.

If the string value can't be converted to a numeric, date, or time format, it will result in an error. You'll then need
use CAST or CONVERTfor the conversion.

SELECT PARSE('Monday, 13 August 2012' AS datetime2 USING 'en-US') AS 'Date in English'


Date in English
2012-08-13 00:00:00.0000000

Section 43.4: Logical and Mathmetical Function


SQL has two logical functions – andIIF .
CHOOSE

The CHOOSEfunction returns an item from a list of values, based on its position in the list. This position is specified
by the index.

In the syntax, the index parameter specifies the item and is a whole number, or integer. The val_1 … val_n
parameter identifies the list of values.

SELECT CHOOSE(2, 'Human Resources', 'Sales', 'Admin', 'Marketing' ) AS Result;


Result
Sales

In this example, you use the


CHOOSEfunction to return the second entry in a list of departments.

The IIF function returns one of two values, based on a particular condition. If the condition is true, it will return
true value. Otherwise it will return a false value.

In the syntax, the boolean_expression parameter specifies the Boolean expression. The true_value parameter
specifies the value that should be returned if the boolean_expression evaluates to true and the false_value
parameter specifies the value that should be returned if the boolean_expression evaluates to false.

SELECT BusinessEntityID, SalesYTD,


IIF(SalesYTD > 200000, 'Bonus', 'No Bonus') AS 'Bonus?'
FROM Sales.SalesPerson
GO
BusinessEntityID SalesYTD Bonus?
274 559697.5639 Bonus
275 3763178.1787 Bonus
285 172524.4512 No Bonus

In this example, you use the IIF function to return one of two values. If a sales person's year-to-date sales are abo
200,000, this person will be eligible for a bonus. Values below 200,000 mean that employees don't qualify for
bonuses.

SQL includes several mathematical functions that you can use to perform calculations on input value
return numeric results.

One example is theSIGN function, which returns a value indicating the sign of an expression. The value of -1
indicates a negative expression, the value of +1 indicates a positive expression, and 0 indicates zero.

GoalKicker.com – SQL Notes for Professionals 121


SELECT SIGN(-20) AS 'Sign'
Sign
-1

In the example, the input is a negative number, so the Results pane lists the result -1.

Another mathematical function is the


POWERfunction. This function provides the value of an expression raised to a
specified power.

In the syntax, the float_expression parameter specifies the expression, and the y parameter specifies the power t
which you want to raise the expression.

SELECT POWER(50, 3) AS Result


Result
125000

GoalKicker.com – SQL Notes for Professionals 122


Chapter 44: Functions (Analytic)
You use analytic functions to determine values based on groups of values. For example, you can use this type of
function to determine running totals, percentages, or the top result within a group.

Section 44.1: LAG and LEAD


The LAG function provides data on rows before the current row in the same result set. For example, in a
SELECT
statement, you can compare values in the current row with values in a previous row.

You use a scalar expression to specify the values that should be compared. The offset parameter is the number o
rows before the current row that will be used in the comparison. If you don't specify the number of rows, the
default value of one row is used.

The default parameter specifies the value that should be returned when the expression at offsetNULL
hasvalue.
a If
you don't specify a value, a valueNULL
of is returned.

The LEAD function provides data on rows after the current row in the row set. For example, in a statement,
SELECT
you can compare values in the current row with values in the following row.

You specify the values that should be compared using a scalar expression. The offset parameter is the number of
rows after the current row that will be used in the comparison.

You specify the value that should be returned when the expression at offset NULL
has avalue using the default
parameter. If you don't specify these parameters, the default of one row is used and a value
NULLof
is returned.

SELECT BusinessEntityID, SalesYTD,


LEAD(SalesYTD, 1, 0) OVER(ORDER BY BusinessEntityID) AS "Lead value",
LAG(SalesYTD, 1, 0) OVER(ORDER BY BusinessEntityID) AS "Lag value"
FROM SalesPerson;

This example uses the LEAD and LAG functions to compare the sales values for each employee to date with those
the employees listed above and below, with records ordered based on the BusinessEntityID column.

BusinessEntityID SalesYTD Lead value Lag value


274 559697.5639 3763178.1787 0.0000
275 3763178.1787 4251368.5497
559697.5639
276 4251368.5497 3189418.3662 3763178.1787
277 3189418.3662 1453719.4653 4251368.5497
278 1453719.4653 2315185.6110 3189418.3662
279 2315185.6110 1352577.1325 1453719.4653

Section 44.2: PERCENTILE_DISC and PERCENTILE_CONT


The PERCENTILE_DISC function lists the value of the first entry where the cumulative distribution is higher than the
percentile that you provide using the
numeric_literal parameter.

The values are grouped by rowset or partition, as specified byWITHIN


the GROUPclause.

The PERCENTILE_CONTfunction is similar to the


PERCENTILE_DISC function, but returns the average of the sum of
the first matching entry and the next entry.

GoalKicker.com – SQL Notes for Professionals 123


SELECT BusinessEntityID, JobTitle, SickLeaveHours,
CUME_DIST() OVER(PARTITION BY JobTitle ORDER BY SickLeaveHours ASC)
AS "Cumulative Distribution",
PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY SickLeaveHours)
OVER(PARTITION BY JobTitle) AS "Percentile Discreet"
FROM Employee;

To find the exact value from the row that matches or exceeds the 0.5 percentile, you pass the percentile as the
numeric literal in the
PERCENTILE_DISC function. The Percentile Discreet column in a result set lists the value of the
row at which the cumulative distribution is higher than the specified percentile.

BusinessEntityID JobTitle SickLeaveHours Cumulative Distribution Percentile Discreet


272 Application Specialist 55 0.25 56
268 Application Specialist 56 0.75 56
269 Application Specialist 56 0.75 56
267 Application Specialist 57 1 56

To base the calculation on a set of values, you usePERCENTILE_CONT


the function. The "Percentile Continuous"
column in the results lists the average value of the sum of the result value and the next highest matching value.

SELECT BusinessEntityID, JobTitle, SickLeaveHours,


CUME_DIST() OVER(PARTITION BY JobTitle ORDER BY SickLeaveHours ASC)
AS "Cumulative Distribution",
PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY SickLeaveHours)
OVER(PARTITION BY JobTitle) AS "Percentile Discreet",
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY SickLeaveHours)
OVER(PARTITION BY JobTitle) AS "Percentile Continuous"
FROM Employee;
Cumulative Percentile Percentile
BusinessEntityID JobTitle SickLeaveHours
Distribution Discreet Continuous
272 Application Specialist 55 0.25 56 56
268 Application Specialist 56 0.75 56 56
269 Application Specialist 56 0.75 56 56
267 Application Specialist 57 1 56 56

Section 44.3: FIRST_VALUE


You use theFIRST_VALUE function to determine the first value in an ordered result set, which you identify using a
scalar expression.

SELECT StateProvinceID, Name, TaxRate,


FIRST_VALUE(StateProvinceID)
OVER(ORDER BY TaxRate ASC) AS FirstValue
FROM SalesTaxRate;

In this example, the


FIRST_VALUE function is used to return the
ID of the state or province with the lowest tax rate.
The OVERclause is used to order the tax rates to obtain the lowest rate.

StateProvinceID Name TaxRate FirstValue


74 Utah State Sales Tax 5.00 74
36 Minnesota State Sales Tax 6.75 74
30 Massachusetts State Sales Tax 7.00 74

GoalKicker.com – SQL Notes for Professionals 124


1 Canadian GST 7.00 74
57 Canadian GST 7.00 74
63 Canadian GST 7.00 74

Section 44.4: LAST_VALUE


The LAST_VALUE function provides the last value in an ordered result set, which you specify using a scalar
expression.

SELECT TerritoryID, StartDate, BusinessentityID,


LAST_VALUE(BusinessentityID)
OVER(ORDER BY TerritoryID) AS LastValue
FROM SalesTerritoryHistory;

This example uses the


LAST_VALUE function to return the last value for each rowset in the ordered values.

TerritoryID StartDate BusinessentityID LastValue


1 2005-07-01 00.00.00.000 280 283
1 2006-11-01 00.00.00.000 284 283
1 2005-07-01 00.00.00.000 283 283
2 2007-01-01 00.00.00.000 277 275
2 2005-07-01 00.00.00.000 275 275
3 2007-01-01 00.00.00.000 275 277

Section 44.5: PERCENT_RANK and CUME_DIST


The PERCENT_RANKfunction calculates the ranking of a row relative to the row set. The percentage is based on the
number of rows in the group that have a lower value than the current row.

The first value in the result set always has a percent rank of zero. The value for the highest-ranked – or last – valu
in the set is always one.

The CUME_DISTfunction calculates the relative position of a specified value in a group of values, by determining th
percentage of values less than or equal to that value. This is called the cumulative distribution.

SELECT BusinessEntityID, JobTitle, SickLeaveHours,


PERCENT_RANK() OVER(PARTITION BY JobTitle ORDER BY SickLeaveHours DESC)
AS "Percent Rank",
CUME_DIST() OVER(PARTITION BY JobTitle ORDER BY SickLeaveHours DESC)
AS "Cumulative Distribution"
FROM Employee;

In this example, you use an


ORDERclause to partition – or group – the rows retrieved by SELECT
the statement based
on employees' job titles, with the results in each group sorted based on the numbers of sick leave hours that
employees have used.

BusinessEntityID JobTitle SickLeaveHours Percent Rank Cumulative Distribution


267 Application Specialist 57 0 0.25
268 Application Specialist 56 0.333333333333333 0.75
269 Application Specialist 56 0.333333333333333 0.75
272 Application Specialist 55 1 1

GoalKicker.com – SQL Notes for Professionals 125


Assitant to the Cheif Financial
262 48 0 1
Officer
239 Benefits Specialist 45 0 1
252 Buyer 50 0 0.111111111111111
251 Buyer 49 0.125 0.333333333333333
256 Buyer 49 0.125 0.333333333333333
253 Buyer 48 0.375 0.555555555555555
254 Buyer 48 0.375 0.555555555555555

The PERCENT_RANKfunction ranks the entries within each group. For each entry, it returns the percentage of entries
in the same group that have lower values.

The CUME_DISTfunction is similar, except that it returns the percentage of values less than or equal to the current
value.

GoalKicker.com – SQL Notes for Professionals 126

You might also like