SOL
Notes for Professionals
Scanned with CamScannerContents
Chapter 3: Data Types
Section 31 DECIMAL ond NUMERIC
Section 3.2: FLOAT and REAL ..
Section 33 Integers ana :
Section 3.4: MONEY ond SMALLMONEY .
INA AE
CHAR and VARCHAR
Section 37: NCHAR and NVARCHAR
Section 3.8 UNIQUEIDENTIFIER
‘Chapter 4: NULL
Section 41: Filtering for NULL IM QUENES sancnanen
ing fel
tlon 61: Using the wildcard character to select all columns in & qué snes 1
Section 62: SELECT Using Column Aliases
Se Select Individual Column:
i ified numt 9
‘Section 65; Selecting with Condition 20
Section 66: Selecting with CASE . 20
Se 3 a rv 2
Section 610: Selecting without Locking the toble
lon 611: Selecting with Aggregate functions
ion 614: Selection with sorted Result
‘Section 6115: Selecting with aul
Section 616: Select distinct (uniaue values onl
Section 617; Select rows from multiple tables
Chapter 7: GROUP BY
Section 21: Basic GROUP BY 2x0MDle .ncunnnnsnnnnnnnininnintntnnninnnininannnnsents a
Section 7.2: Filter GROUP BY results using o HAVING clause . 2B
P BY f . inioue ent
Section 7.4: ROLAP aggregation (Date Mining) ...
Scanned with CamScannerChapter 8: ORDER BY
Chapter 9: AND & OR Operators
Section 911 AND OR Example .....
Chapter 10: CASE
101: U:
jection 10.2: Search
4
‘Section 10.4: Shorthand CASE in SELECT
9 10.5: Using CASE in UPDA’
Section 10.6: CASE use for NULL values ordered last
Chapter 11: LIKE operator
it Ti Mote et ei tH cincinnati ianionintiiitnisiiinkin
tion 112: Single character match os
Section 113: ESCAPE statement in the LIKE-query
‘Section 114 Search fora range of characters ..
Section 115: Match by range or set
‘Section 11.6 Wildcard characters
Chapter 12: IN clause
Section 121 Simple IN clouse
Section 122. Using IN cause with o
rains 43
Section 131: Use BETWEEN to Fiter Results .
Section 152: Use HAVING with Aggregote Functions
tion 139: Where EXISTS anon
Section 1310. Use HAVING to check for multiple conditions in a grou
hapter 14: SKIP TAKE (Pagination) ........
Section 14. Limiting omount of results ..
Section 143. Skioping some rows from result
Chapter 15: EXCEPT ..
tion 15,1: Select dataset except where values are in this other GOtaset innnnminmnnnnnnnnmnnnsnennne 52,
Chapter 16: EXPLAIN and DESCRIBE
Section 161: EXPLAIN Select query .
Section 162: DESCRIBE teblenome,
ter 17: EXi: USE ...
Section 171. EXISTS CLAUSE
‘Chapter 18: JOIN
Scanned with CamScannerSection 18% Self Join .
Section 182. Differences between inner/outer joins
ci 56
tion 18.3: JOIN Terminology: Inner, Outer. Semi AML. sesnnn 59
n 18.4 Join
Section 1810: Bosic explicit inner join
18: Joinin:
Chapter 19: UPDATE
Chapter 20: CREATE Database .
Section 201: CREATE Database
Chapter 25: TRY/CATCH
Section 231: Tronsaction in © TRY/CATCH nuns
ter 24: UNI Al “
Section 241: Bosic UNION ALL query ..
Section 242: Simple explanation and Exomple
Chapter 25: ALTER TABLE
Section 251, Add Column(s)
Section 252: Drop Column . . .
‘Section 253: Add Primary Key me ™ Ps ~ . 86
tion 264: Insert
Chapter 27: MERGE
Section 27:1: MERGE to make Target match Sour.
ection 27.2: MuSQL. counting users by name
‘Section 273: PostgreSQL: counting users by name...
ultiple rows at
Scanned with CamScannerChapter 29: DELETE
Chapter 31: DROP Table
Section 311: Check for existence before dropping ..
‘Section 321: DROP Detabase ..
Chapter 33: Cascading Delete
33
Chapter 35: XML
Section 351: Query from XML Doto Type... ri stat i see 100,
Section 373: Crecting Gn INGEX .snens
Section 37.4: Dropping an index or Discbling and Rebuilding it
on 37.6: Bi index ..
9 377. Inserting
2 Re en
Section 38.2: Row numbers without pertitions
tion 383: Row numbers with partitions...
Chapter 39: SOL Group By vs Distinct
Section 391: Difference between GROUP BY and D/STIN so
Chapter 40: Finding Duplicates on a Column Subset with Detail
Section 401: Students with same name ond cote of birth
chapter 41: String Fi ic
Section 411: Concotencte
‘Section 412 Length
Section 413. Trim empty spaces
Section 414: Upper & lower case
Section 415: Solit
Section 416: Replace
Section 417: REGEX®
‘Section 41.8: Substring
Section 419: Stuff
Section
Scanned with CamScannerSection 411: REVERSE seneee WA
Section 4112: REPLICATE isso
4113: Replace function in sql Select an ry soe M1
Section 4114: INSTA .. 12
112
114
4
Section 42.2; List Concatenation 14
SECTION 42.3: SUM ..s.sccson tee seananese woe scsenssconensiononsenan sevenssasnees 116
Section 424: AVGO 16
Section 425: Count 116
Section 426 Min "7
Section 427: Max
Chapter 43: Functions (Scalar/Single Row) ......
Section 431: Date And Time
118
119
ng
‘Section 43.2: Character modifications 120
Section 433: Configuration and Conversion Function .. =. 120
Section 4: Ico and Mathmetical Funct 121
Chapter 44: Functions (Analytic) .
Section 441: LAG and LEAD.
123
123
124
125
Section 444: LAST VALUE
" N 125
fer 45: Wi Fui S 127
lon 451: Settin flag if other rows have a common properti on 127
Section 452. Finding "out-of-sequence” records using the LAGO function .... : 127
Section 45 3: Getting a running total... a ss 128
n 45.4: Adding the total r 128
i 1 « st 129
46: bI 130
Section 461; generating volues 130
130
snnennsssinnnnnnesnie TI
EG
132
132
134
134
134
135
135
136
136
136
17
137
137
139
tion 465: Temporary query.
Scanned with CamScannertion S11: Create Sequenc:
Section 512: Using Sequences
Section 52.4: Correlated Subaueries
Section 525: Filter query results using query on different table
Section 526: Subquerles In FROM CIQUS€. sues tenn
ection 527: Subqueries in WHERE cloust
Chapter 53: Execution blocks
Section $31: Using BEGIN. END
chapter. tor
n 541: Create ank
Section 581 Create SuNOAYM anu
Chapter 59: Information Schema
ection 591. Basic information Schema Search .
Chapter 60: Order of Execution
ion 601: Logical Order of Quer
hapter 61: Clean in ~
ection 611: Form:
Section 612: indenting
Section 613: SELECT *
Section 614: Joins ..
151
sue 152
Scanned with CamScannerAbout
Please feel free to share this PDF with anyone for free,
latest version of this book can be downloaded from:
hittps://goalkicker.com/SQLBook
This SQL Notes for Professionals book is compiled from Stack Overflow
Documentation, the content is written by the beautiful people at Stack Overflow.
Text content is released under Creative Commons BY-SA, see credits at the end
of this book whom contributed to the various chapters. Images may be copyright
of their respective owners unless otherwise specified
This is an unofficial free book created for educational purposes and is not
affiliated with official SQL group(s) or company(s) nor Stack Overflow. All
trademarks and registered trademarks are the property of their respective
company owners
The information presented in this book is not guaranteed to be correct nor
accurate, use at your own risk
Please send feedback and corrections to
[email protected]
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScannerChapter 1: Getting started with SQL
Version Short Name Standard Release Date
1986 SQL-86 ANSI X3.135-1986, ISO 9075:1987 1986-01-01
1989 SQL-89 ANSI X3.135-1989, ISO/IEC 9075:1989 1989-01-01
1992 SQL-92 ISO/IEC 9075:1992 1992-01-01
1999 SQL:1999 ISO/IEC 9075:1999 1999-12-46
2003 © $QL:2003 ISO/IEC 9075:2003 2003-12-15
2006 © SQL:2006 ISO/IEC 9075:2006 2006-06-01
2008 © SQL:2008 ISO/IEC 9075:2008 2008-07-15
2011 SQL:2011ISO/EC 9075:2011 2011-12-15
2016 SQL:2016 ISO/IEC 9075:2016 2016-12-01
Section 1.1: Overview
Structured Query Language (SQL) is a special-purpose programming language designed for managing data held in a
Relational Database Management System (RDBMS). SQLlike languages can also be used in Relational Data Stream
Management Systems (ROSMS), or in "not-only SQL” (NoSQL) databases.
SQL comprises of 3 major sub-languages:
1. Data Definition Language (DDL): to create and modify the structure of the database;
2. Data Manipulation Language (DML): to perform Read, Insert, Update and Delete operations on the data of
the database;
3. Data Control Language (DCL): to control the access of the data stored in the database.
SQL article on Wikipedia
‘The core DML operations are Create, Read, Update and Delete (CRUD for short) which are performed by the
staternents TNSERT, SELECT, UPDATE and DELETE.
‘There is also a (recently added) NERGE statement which can perform all 3 write operations (INSERT, UPDATE,
DELETE).
CRUD article on Wikipedia
Many SQL databases are implemented as client/server systems; the term "SQL server" describes such a database.
At the same time, Microsoft makes a database that is named "SQL Server". While that database speaks a dialect of
SQL, information specific to that database is not on topic in this tag but belongs into the SQL Server documentation.
Goalkicker.com = SQL Notes for Professionals 2
Scanned with CamScannerChapter 2: Identifier
identifiers, ie. syntax rules for names of tables, columns, and other database objects.
This topic is about
Where appropriate, the examples should cover variations used by different SQL implementations, or identify the
SQL implementation of the example.
Section 2.1: Unquoted identifiers
Unquoted identifiers can use letters (a-z), digits (8-9), and underscore (_), and must start with a letter.
Depending on SQL implementation, and/or database settings, other characters may be allowed, some even as the
first character, e.g.
Ms SQL:@, §, #, and other Unicode letters (source)
MySQL: $ (source)
Oracle: , #, and other letters from database character set (source)
PostgreSQL: $, and other Unicode letters (source)
Unquoted identifiers are case-insensitive. How this is handled depends greatly on SQL implementation:
‘+ MS SQL: Case-preserving, sensitivity defined by database character set, so can be case-sensitive.
MySQL: Case-preserving, sensitivity depends on database setting and underlying file system.
Oracle: Converted to uppercase, then handled like quoted identifier.
PostgreSQL: Converted to lowercase, then handled like quotes identifier.
‘SQLite: Case-preserving; case insensitivity only for ASCII characters.
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScannerChapter 3: Data Types
Section 3.1: DECIMAL and NUMERIC
Fixed precision and scale decimal numbers. DECIMAL and NUNERIC are functionally equivalent.
Syntax:
DECIMAL ( precision | , scale]
NUMERIC ( precision | , scale] )
Examples:
SELECT CAST(123 AS DECIMAL(S,2)) --returns 123.06
SELECT CAST(12345.12 AS NUMERIC(1@,5)) --returns 12345.12000
Section 3.2: FLOAT and REAL
Approximate-number data types for use with floating point numeric data.
SELECT CAST( PI() AS FLOAT) --returns 3.14159265358979
SELECT CAST( PI() AS REAL) --returns 3.141593
Section 3.3: Integers
Exact-number data types that use integer data.
Data type Range Storage
bigint — -2963 (-9,223,372,036,854,775,808) to 263-1 (9,223,372,036,854,775,807) 8 Bytes
int “2031 (-2,147,483,648) to 2931-1 (2,147,483,647) 4Bytes
smallint -215 (32,768) to 25-1 (32,767) 2Bytes
tinyint. 0 t0 255 1 Byte
Section 3.4: MONEY and SMALLMONEY
Data types that represent monetary or currency values.
Data type Range Storage
money _-922,337,203,685,477.5808 to 922,337,203,685,477.5807 8 bytes
smallmoney -214,748.3648 to 214,748.3647 Abytes
Section 3.5: BINARY and VARBINARY
Binary data types of elther fixed length or variable length
syntax:
BINARY | ( n_bytes ) |
VARBINARY [ ( nbytes | max )
n_bytes can be any number from 1 to 8000 bytes. max indicates that the maximum storage space is 2°31-1
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScannerExamples:
‘SELECT CAST(12345 AS BINARY(10)) -- @xooaeeeaa0e0000003039
SELECT CAST(12345 AS VARBINARY(18)) -- @xo0003039
Section 3.6: CHAR and VARCHAR
String data types of either fixed length or variable length.
Syntax:
CHAR | ( nchars )
VARCHAR [ (n_chars ) |
Examples:
SELECT CAST(‘ABC* AS CHAR(1@)) -- “ABC * (padded with spaces on the right)
SELECT CAST('ABC' AS VARCHAR(1@)) -- ‘ABC’ (no padding due to variable character)
‘SELECT CAST(' ABCDEFGHTJKLMNOPORSTUVWXYZ" AS. CHAR(1@))
ABCDEFGHIJ' (truncated to 1@ cha
Section 3.7: NCHAR and NVARCHAR
UNICODE string dats types of either fixed length or variable length.
Syntax:
NCHAR [ ( nchars ) |
VARCHAR [ ( nchars | MAX ) ]
Use Wax for very long strings that may exceed 8000 characters.
Section 3.8: UNIQUEIDENTIFIER
A16-byte GUID / UID.
DECLARE @GUID UNIQUEIDENTIFIER = NEWID()
SELECT @GUID -- 'E28838D9-9174-41A9-8508-899A78A33540.
DECLARE @bad_GUID_string VARCHAR(1@@) = E28838D9-9174-41A9-8508-899A78A33540_foobarbaz*
‘SELECT
@bad_GUID_string, ~~ "£28B98D9-9174~41A9-8508-899A78A33549_foobarbaz
CONVERT(UNIQUETDENTIFIER, @bad_GUID_string) -- “£28B3B)9-9174-41A9-8508-899A78A33540"
Goalkicker.com = SQL Notes for Professionals 5
Scanned with CamScannerChapter 4: NULL
NULL in SQL, as well as programming in general, means literally "nothing". In SQL, itis easier to understand as "the
absence of any value".
portant to distinguish it from seemingly empty values, such as the empty string "or the number 8, neither
of which are actually NULL.
Itis also important to be careful not to enclose NULL in quotes, like NULL’, which is allowed in columns that accept
text, butis not NULL and can cause errors and incorrect data sets.
Section 4.1: Filtering for NULL in queries
The syntax for filtering for NULL (i.e. the absence of a value) in WHERE blocks is slightly different than filtering for
specific values.
SELECT * FROM Employees WHERE ManagerId IS NULL
SELECT = FROM Employees WHERE ManagerId IS NOT NULL
Note that because NULL is not equal to anything, not even to itself, using equality operators - NULL or <> NULL (or
| NULL) will aways yield the truth value of UNKNOIN which will be rejected by WHERE.
HERE filters all rows that the condition is FALSE or UKNONN and keeps only rows that the condition is TRUE.
Section 4.2: Nullable columns in tables
When creating tables it is possible to declare a column as nullable or non-nullable.
CREATE TABLE MyTable
MyColt INT NOT NULL, ~~ non-nullable
Mycol? INT NULL -- nullable
By default every column (except those in primary key constraint) is nullable unless we explicitly set NOT NULL.
constraint.
Attempting to assign NULL to a non-nullable column will result in an error.
INSERT INTO MyTable (MyCol1, MyCol2) VALUES (1, NULL) ; -- works fine
INSERT INTO HyTable (MyCol1, HyCol2) VALUES (NULL, 2)
cannot insert
the value NULL into column "MyCol1', table ‘MyTable’ ;
column does not allow nulls. INSERT fails
Section 4.3: Updating fields to NULL
Setting a field to NULL works exactly like with any other value:
UPDATE Employees
SET ManagerId = NULL
WHERE Td = 4
Goalkicker.com = SQL Notes for Professionals é
Scanned with CamScannerSection 4.4: Inserting rows with NULL fields
For example inserting an employee with no phone number and no manager into the Employees example table:
INSERT INTO Employees
(Td, FName, Name, PhoneNumber, ManagerId, DepartmentId, Salary, HireDate)
VALUES
(5, ‘Jane’, ‘Doe", NULL, NULL, 2, 808, ‘2016-07-22")
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScannerChapter 5: Example Databases and Tables
Section 5.1: Auto Shop Database
In the following example - Database for an auto shop business, we have a list of departments, employees,
customers and customer cars. We are using foreign keys to create relationships between the various tables.
Live example: SOI fiddle
Relationships between tables
‘+ Each Department may have 0 or more Employees
‘+ Each Employee may have 0 or 1 Manager
‘+ Each Customer may have 0 or more Cars
Departments
ld Name
THR
2 Sales
3 Tech
SQL statements to create the table:
CREATE TABLE Departments (
Id INT NOT NULL AUTO_INCREMENT.
Name VARCHAR(25) NOT NULL
PRIMARY KEY (Td)
INSERT INTO Departments
((1¢], [Name])
VALUES
(1, ‘HR:
(2, *Sales")
(3, 'Tech*)
Employees
IdFName — LName PhoneNumber Managerid Departmentld Salary HireDate
1 james Smith 1234567890 NULL 1 1000 01-01-2002
2 John Johnson 24681012141 1 400 23-03-2005
3 Michael Williams 13579111311 2 600 12-05-2009
4 Johnathon Smith 1212121212 2 1 500 24-07-2016
SQL statements to create the table:
CREATE TABLE Employees
Td INT NOT NULL AUTO_INCREMENT.
FName VARCHAR(35) NOT NULL,
LName VARCHAR(35) NOT NULL,
PhoneNumber VARCHAR( 11)
Managerid INT.
DepartmentId INT NOT NULL,
Goalkicker.com = SQL Notes for Professionals @
Scanned with CamScannerSalery INT NOT NULL.
HireDate DATETIME NOT NULL
PRIMARY KEY (Id)
FOREIGN KEY (ManagerId) REFERENCES Employees(Id)
FOREIGN KEY (DepartmentId) REFERENCES Departments(Td)
iB
INSERT INTO Employees
([¢), [FName], [LName], [PhoneNumber], |ManagerId), (Departmentid), (Salary
VALUES
(1, ‘James’, ‘Smith’, 1234567890, NULL, 1, 1808, '61-01-2002')
(2, ‘John’, ‘Johnson’, 2468181214, 1°, 1, 498, '23-@3-2005' )
(2, ‘Michael’, ‘Williams’, 1357911131, '1', 2, 608, '12-85-2009"),
(4, ‘Johnathon’, ‘Smith’, 1212121212 1, 500, °24-07-2016")
Customers
Id FName LName Email PhoneNumber PreferredContact
1 William Jones
[email protected] 3347927472 PHONE
2 David Miller
[email protected] 2137921892 EMAIL
3 Richard Davis
[email protected] NULL EMAIL
SQL statements to create the table:
CREATE TABLE Customers (
Id INT NOT NULL AUTO_INCREMENT,
FName VARCHAR(35) NOT NULL,
LName VARCHAR(35) NOT NULL,
Email verchar(10@) NOT NULL.
PhoneNumber VARCHAR(11)
PreferredContact VARCHAR(S) NOT NULL.
PRIMARY KEY (Id)
INSERT INTO Customers
([¢), [FName], [LName|, [Email], |PhoneNumber}, [PreferredContact)
VALUES
“Jones*, ‘william. jonestexample.com’, '3347927472', ‘PHONE')
(2, ‘David’, ‘Miller’, “dmillertexample.net', '2137921892", ‘EMAIL')
(3, ‘Richard’, ‘Davis’, ‘
[email protected]’, NULL, "EMAIL")
Cars
Id Customerid Employeeld Model Status Total Cost
1 2 FordF-150 READY 230
21 2 FordF-150 READY 200
32 1 Ford Mustang WAITING 100
aa 3 Toyota Prius WORKING 1254
SQL statements to create the table:
CREATE TABLE Cars (
Id INT NOT NULL AUTO_INCREMENT.
CustomerId INT NOT NULL.
EmployeeId INT NOT NULL
Wodel varchar(5@) NOT NULL,
Status varchar(25) NOT NULL
[HireDate])
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScannerTotalcost INT NOT NULL.
PRIMARY KEY (Id)
FOREIGN KEY (CustomerId) REFERENCES Customers (Id),
FOREIGN KEY (EmployeeId) REFERENCES Employees (Id)
INSERT INTO Cars
(1d), [Customertd), [EmployeeId), |Model), (Stetus|, [Totelcost))
VALUES
(1), "11, '2", "Ford F-188", ‘READY’, '230'),
2, '1!) '2", ‘Ford F-15", ‘READY’, ‘208'),
3°, '2', ‘1°, ‘Ford Mustang’, ‘WAITING’, ‘100° )
4°/ °3'| '3", ‘Toyota Prius’, ‘WORKING’, ‘1254')
Section 5.2: Library Database
In this example database for a library, we have Authors, Books and BooksAuthors tables.
Live example: SOI fiddle
Authors and Books are known as base tables, since they contain column definition and data for the actual entities in
the relational model. BooksAuthors is known as the relationship table, since this table defines the relationship.
between the Books and Authors table.
Relationships between tables
‘* Each author can have 1 or more books
‘+ Each book can have 1 or more authors
‘Authors
(view table)
IdName Country
1 |.D. Salinger USA
2 F. Scott. Fitzgerald USA
3 Jane Austen UK
4 Scott Hanselman USA
5 Jason N. Gaylord USA
6 Pranav Rastogi India
7 Todd Miranda USA
8 Christian Wenz USA
SQL to create the table:
CREATE TABLE Authors (
Id INT NOT NULL AUTO_INCREMENT.
Name VARCHAR(7@) NOT NULL,
Country VARCHAR(108) NOT NULL,
PRIMARY KEY (Id)
INSERT INTO Authors
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
0(Name, Country)
VALUES
(J.D. Salinger’, 'USA’)
(CF. Scott. Fitzgerald’, ‘USA')
(‘Jane Austen’, ‘UK")
(‘Scott Hanselman’, ‘USA’)
(‘Jason N. Gaylord’, ‘UsA’)
(‘Pranav Rastogi’, ‘India")
(‘Todd Miranda’, *usa’)
(‘Christian Wenz’, ‘USA')
Books
(view table)
id
1 The Catcher in the Rye
2 Nine Stories
3 Franny and Zooey
4 The Great Gatsby
5 Tender id the Night
6 Pride and Prejudice
7 Professional ASP.NET 4.5 in C# and VB
SQL to create the table:
CREATE TABLE Books (
Id INT NOT NULL AUTO_INCREMENT,
Title VARCHAR(5®) NOT NULL,
PRIMARY KEY(Id)
o
INSERT INTO Books
(Id, Title)
VALUES
(1, ‘The Catcher in the Rye’),
(2, ‘Nine Stories"),
(3, ‘Franny and Zooey’)
(4, ‘The Great Gatsby’)
(5, ‘Tender id the Night" )
(6, ‘Pride and Prejudice’),
(7, ‘Professional ASP.NET 4.5 in C# and VB’)
BooksAuthors
(view table)
Bookid Authorid
1 1
1
wR wn
Goalkicker.com = SQL Notes for Professionals 7
Scanned with CamScannerNuvo
SQL to create the table:
CREATE TABLE BooksAuthors (
AuthorId INT NOT NULL,
BookTd INT NOT NULL.
FOREIGN KEY (AuthorId) REFERENCES Authors(I¢)
FOREIGN KEY (BookId) REFERENCES Books (Id)
)
INSERT INTO BooksAuthors
(Booktd, Authorid)
VALUES
ay
(2, 1)
(3, 1)
(4, 2)
(5, 2)
(6, 3),
(7, 4)
(7, 5),
(7, 6)
(7, 7)
(7, 8)
Examples
View all authors (view live example):
SELECT » FROM Authors;
View all book titles (view live example):
SELECT * FROM Books
View all books and their authors (view live example):
‘SELECT
ba.AuthorId,
a.Nare AuthorName.
ba. BookId,
b.Title BookTitle
FROM BooksAuthors ba
INNER JOIN Authors a ON a.id = ba.authorid
INNER JOIN Books b ON b.i¢ = ba.bookid
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
2Section 5.3: Countries Table
In this example, we have a Countries table. A table for countries has many uses, especially in Financial applications
involving currencies and exchange rates.
Live example: SOL fiddle
Some Market data software applications like Bloomberg and Reuters require you to give their API either a 2 or 3
character country code along with the currency code. Hence this example table has both the 2-character 150 code
column and the 3 character 1803 code columns.
Countries
(Wiew table)
Id 180 1SO31SONumeric CountryName Capital _ContinentCode CurrencyCode
1 AU AUS 36 Australia Canberra. OC AUD
2 DE DEU 276 Germany Ber eu EUR
2 IN IND 356 India New Delhi AS INR
3 1A LAO 418 Laos Vientiane AS LAK
4US USA 840 United States Washington NA usD
5 ZW ZWE 716 Zimbabwe Harare AF ZL
SQL to create the table:
CREATE TABLE Countries
Id INT NOT NULL AUTO_INCREMENT.
ISO VARCHAR(2) NOT NULL
1803 VARCHAR(3) NOT NULL.
TSONumeric INT NOT NULL
CountryName VARCHAR(64) NOT NULL
Capital VARCHAR(64) NOT NULL
ContinentCode VARCHAR(2) NOT NULL,
CurrencyCode VARCHAR(3) NOT NULL.
PRIMARY KEY (Td)
INSERT INTO Countries
(180, 1803, IsONumeric, CountryName, Capital, ContinentCode, CurrencyCode)
VALUES
(*AU', ‘AUS’, 36, ‘Australia’, ‘Canberra’, ‘OC’, ‘AUD'),
({DE', “DEU', 276, ‘Germany’, ‘Berlin’, "EU', ‘EUR’)
(CIN, ‘IND’, 356, ‘India’, ‘New Delhi*, "AS*, “INR'),
((LA', “LAO, 418, ‘Laos’, ‘Vientiane’, ‘AS, ‘LAK")
(*US', ‘USA’, 849, ‘United States’, ‘Washington’, ‘NA’, ‘USD’)
((2W, “2WE', 716, ‘Zimbabwe’, ‘Harare’, ‘AF’, “ZWL")
Goalkicker.com = SQL Notes for Professionals 3
Scanned with CamScannerChapter 6: SELECT
‘The SELECT statement is at the heart of most SQL queries. It defines what result set should be returned by the
query, and is almost always used in conjunction with the FROM clause, which defines what partis) of the database
should be queried.
Section 6.1: Using the wildcard character to select all columns
in a query
Consider a database with the following two tables.
Employees table:
Id FName LName Deptid
1 James Smith 3
2 John Johnson 4
Departments table:
Id Name
1 Sales
2 Marketing
3 Finance
air
Simple select statement
+ is the wildcard character used to select all available columns in a table.
When used as a substitute for explicit column names, it returns all columns in all tables that a query is selecting
FROM. This effect applies to all tables the query accesses through its JOTN clauses,
Consider the following query:
SELECT * FROM Employees
twill return all fields of all rows of the Employees table:
Id FName LName Deptid
1 James Smith 3
2 John Johnson 4
Dot not
in
To select all values from a specific table, the wildcard character can be applied to the table with dot notation.
Consider the following quer
SELECT
Employees.»
Departments Name
FROM
Employees
JOIN
Goalkicker.com = SQL Notes for Professionals 4
Scanned with CamScannerDepartments
ON Departments.Id = Employees DeptI¢
This will return a data set with all fields on the Employee table, followed by just the Name field in the Departments
table:
Id FName LName Deptid Name
1 James Smith 3 Finance
2 John Johnson IT
Warnings Against Use
It is generally advised that using + is avoided in production code where possible, as it can cause a number of
potential problems including:
Excess |O, network load, memory use, and so on, due to the database engine reading data that is not needed
and transmitting it to the front-end code. This is particularly a concern where there might be large fields such
as those used to store long notes or attached files.
2. Further excess |O load if the database needs to spool internal results to disk as part of the processing for a
query more complex than SELECT
FROM .
3. Extra processing (and/or even more 10) if some of the unneeded columns are:
© computed columns in databases that support them
© in the case of selecting from a view, columns from a table/view that the query optimiser could
otherwise optimise out
4, The potential for unexpected errors if columns are added to tables and views later that results ambiguous
column names. For example SELECT * FROM orders JOIN people ON people. id = orders.personid ORDER
BY displaynane - if a column column called displayname is added to the orders table to allow users to give
their orders meaningful names for future reference then the column name will appear twice in the output so
the ORDER BY clause will be ambiguous which may cause errors ("ambiguous column name” in recent MS SQL
Server versions), and if not in this example your application code might start displaying the order name
where the person name is intended because the new column is the first of that name returned, and so on.
When Can You Use , Bearing The Above Warning In Mind?
While best avoided in production code, using * is fine as a shorthand when performing manual queries against the
database for investigation or prototype work.
Sometimes design decisions in your application make it unavoidable (in such circumstances, prefer tablealias.»
over just * where possible),
‘When using EXISTS, such as SELECT A.col1, A.Col2 FROM A WHERE EXTSTS (SELECT * FROM B where A.D
8 AID), we are not returning any data from B, Thus a join is unnecessary, and the engine knows no values from B
are to be returned, thus no performance hit for using *. Similarly COUNT *) is fine as it also doesn't actually return
any of the columns, so only needs to read and process those that are used for filtering purposes.
Section 6.2: SELECT Using Column Aliases
Column aliases are used mainly to shorten code and make column names more readable.
Code becomes shorter as long table names and unnecessary identification of columns (e.g. there may be 2 IDs in the
table, but only one is used in the statement) can be avoided. Along with table aliases this allows you to use longer
descriptive names in your database structure while keeping queries upon that structure concise.
Furthermore they are sometimes required, for instance in views, in order to name computed outputs.
Goalkicker.com = SQL Notes for Professionals 5
Scanned with CamScannerAllversions of SQL
Aliases can be created in all versions of SQL using double quotes ("
SELECT
FName AS "First Name’
WName AS "Middle Name"
LNane AS “Last Name"
FROM Employees
Different Versions of SQL
You can use single quotes ('), double quotes (") and square brackets ({ |) to create an alias in Microsoft SQL Server.
SELECT
FNane AS “First Name"
Wane AS ‘Middle Name’
Lane AS [Last Name
FROM Employees
Both will result in:
First Name Middle Name Last Name
James John Smith
John James Johnson
Michael Marcus Williams
This statement will return FName and LName columns with a given name (an alias). This is achieved using the AS
operator followed by the alias, or simply writing alias directly after the column name. This means that the following
query has the same outcome as the above.
‘SELECT
FName
LNane
FROM Employees
First Name Middle Name Last Name
James John Smith
John James Johnson,
Michael Marcus Williams
However, the explicit version (i.e, using the 4S operator) is more readable,
If the alias has a single word that is not a reserved word, we can write it without single quotes, double quotes or
brackets:
SELECT
FName AS FirstName.
LName AS LastName
FROM Employees
FirstName LastName
James Smith
John Johnson
Michael Wiliams
Goalkicker.com = SQL Notes for Professionals 16
Scanned with CamScannerfurther variation available in MS SQL Server amongst others is = , for
instance:
SELECT FullName = FirstName +" ' + LastNane,
Addr1 = FullStreetAddress
Addr? TownName
FROM CustomerDetails
which is equivalent to:
SELECT FirstName + ' * + LastName As FullName
FullstreetAddress As Addr
TownName As Addr
FROM CustomerDetails
Both will result in:
FullName Addrt Addr2
James Smith 123 AnyStreet_ Townville
John johnson 668 MyRoad Anytown
Michael Williams 999 High End Dr Wiliamsburgh
Some find using = instead of As easier to read, though many recommend against this format, mainly because it is
not standard so not widely supported by all databases. It may cause confusion with other uses of the = character.
All Versions of SQL
A'so, if you need to use reserved words, you can use brackets or quotes to escape:
SELECT
FName as "SELECT"
Name as "FROM™
LName as “WHERE”
FROM Employees
Different Versions of SQL
Likewise, you can escape keywords in MSSQL with all different approaches:
SELECT
FName AS "SELECT"
Name AS FROM"
LName AS (WHERE
FROM Employees
SELECT FROM WHERE
James John Smith
John James Johnson
Michael Marcus Williams
A\so, a column alias may be used any of the final clauses of the same query, such as an ORDER BY:
SELECT
FName AS FirstNane,
LName AS LastName
FROM
Goalkicker.com = SQL Notes for Professionals 7
Scanned with CamScannerEmployees
ORDER BY
LastName DESC
However, you may not use
SELECT
FName AS SELECT.
LName AS FROM
FROM
Employees
ORDER BY
LastName DESC
To create an alias from these reserved words (SELECT and FROM).
This will cause numerous errors on execution.
Section 6.3: Select Individual Columns
‘SELECT
PhoneNunber.
Email
PreferredContact
FROM Customers.
This statement will return the columns PhoneNumber, Email, and PreferredContact from all rows of the Customers
table. Also the columns will be returned in the sequence in which they appear in the SELECT clause.
The result will be:
PhoneNumber Email PreferredContact
3347927472 william [email protected] PHONE
2137921892 [email protected] EMAIL
NULL [email protected] EMAIL
If multiple tables are joined together, you can select columns from specific tables by specifying the table name
before the column name: |table_name| . (colunn_nane
‘SELECT
Customers . PhoneNumber,
Customers. Email
Customers. PreferredContact,
Orders.1d AS Orderid
FROM
Customers
LEFT JOIN
Orders ON Orders CustomerId = Customers Id
*AS OrderId means that the Zé field of Orders table will be returned as a column named Order. See selecting
with column alias for further information.
To avoid using long table names, you can use table aliases. This mitigates the pain of writing long table names for
each field that you select in the joins. If you are performing a self join (a join between two instances of the same
table), then you must use table aliases to distinguish your tables. We can write a table alias like Customers c or
Customers AS ¢. Here c works as an alias for Customers and we can select let's say Email like this: ¢ Email.
Goalkicker.com = SQL Notes for Professionals 8
Scanned with CamScannerSELECT
‘¢.PhoneNumber,
Email,
c.PreferredContact
0.1d AS OrderId
FROM
Customers ¢
LEFT JOIN
Orders © ON o.CustomerId = c.1d
Section 6.4: Selecting specified number of records
‘The SQL 2008 standard defines the FETCH FIRST clause to limit the number of records returned.
SELECT Id, ProductName, UnitPrice, Package
FROM Product
ORDER BY UnitPrice DESC
FETCH FIRST 10 ROWS ONLY
This standard is only supported in recent versions of some RDMSS. Vendor-specific non-standard syntax is provided
in other systems. Progress OpenEdge 11.x also supports the FETCH FIRST ROWS ONLY syntax.
Additionally, OFFSET ROWS before FETCH FIRST ROWS ONLY allows skipping rows before fetching rows.
SELECT Id, ProductName, UnitPrice, Package
FROM Product
ORDER BY UnitPrice DESC
OFFSET 5 ROWS
FETCH FIRST 10 ROWS ONLY
The following query is supported in SQL Server and MS Access:
SELECT TOP 18 Id, ProductNane, UnitPrice, Packace
FROM Product
ORDER BY UnitPrice DESC
To do the same in MySQL or PostgreSQL the LIMIT keyword must be used:
SELECT Id, ProductName, UnitPrice, Package
FROM Product
ORDER BY UnitPrice DESC
LIMIT 1@
In Oracle the same can be done with ROWNUM:
SELECT Id, ProductName, UnitPrice, Package
FROM Product
WHERE ROWNUM <= 10
ORDER BY UnitPrice DESC
Results: 10 records.
Id ProductName unitPrice Package
38 Céte de Blaye 263.50 12 - 75 cl bottles
29 Thiringer Rostbratwurst 123.79 50 bags x 30 sausgs.
9 Mishi Kobe Niku 97.09 18 - 509 9 pkgs.
Goalkicker.com = SQL Notes for Professionals 9
Scanned with CamScanner28 Sir Rodney's Marmalade 81.00 30 gift boxes
18 Carnarvon Tigers 62.50 16 kg pkg.
59 Raclette Courdavault 55.00 5 kg pkg.
51 Manjimup Dried Apples 53.00 50 - 300 9 pkgs.
62 Tarte au sucre 49.30 48 pies
43 Ipoh Coffee 46.00 16 = 500 g tins
28 Rosle Sauerkraut 45.60 25 - 825 9 cans
Vendor Nuances:
Itis important to note that the ToP in Microsoft SQL operates after the WHERE clause and will return the specified
number of results if they exist anywhere in the table, while RORNUM works as part of the WHERE clause so if other
conditions do not exist in the specified number of rows at the beginning of the table, you will get zero results when
there could be others to be found.
Section 6.5: Selecting with Condition
The basic syntax of SELECT with WHERE clause is:
SELECT column, colunn2, columN
FROM table_name
WHERE [condition
The [condition] can be any SQL expression, specified using comparison or logical operators like >, <
UKE, NOT, IN, BETWEEN etc.
The following statement returns all columns from the table ‘Cars’ where the status column is ‘READY’:
SELECT * FROM Cars WHERE status = ‘READY’
See WHERE and HAVING for more examples.
Section 6.6: Selecting with CASE
‘When results need to have some logic applied ‘on the fiy one can use CASE statement to implement it.
SELECT CASE WHEN Coll < 5@ THEN ‘under’ ELSE ‘over’ END threshold
FROM TableName
also can be chained
SELECT
CASE WHEN Colt < $8 THEN ‘under:
WHEN Col1 > 50 AND Colt <100 THEN ‘betneen’
ELSE ‘over
END threshold
FROM TableName
one also can have CASE inside another CASE statement
SELECT
‘CASE WHEN Coll < 50 THEN ‘under:
ELSE
CASE WHEN Col1 > 58 AND Colt <108 THEN Col1
ELSE ‘over’ END
END threshold
Goalkicker.com = SQL Notes for Professionals 20
Scanned with CamScannerFROM TableName
Section 6.7: Select columns which are named after reserved
keywords
‘When a column name matches a reserved keyword, standard SQL requires that you enclose it in double quotation
marks:
SELECT
“ORDER”
1D
FROM ORDERS
Note that it makes the column name case-sensitive.
‘Some DBMSes have proprietary ways of quoting names. For example, SQL Server uses square brackets for this
purpose:
‘SELECT
[order]
1D
FROM ORDERS
while MySQL (and MariaDB) by default use backticks:
‘SELECT
order
id
FROM orders
Section 6.8: Selecting with table alias
SELECT e.Fname, e.LName
FROM Employees ©
‘The Employees table is given the alias ‘e' directly after the table name. This helps remove ambiguity in scenarios
where multiple tables have the same field name and you need to be specific as to which table you want to return
data from.
SELECT e.Fname, e.LName, m.Fname AS ManagerFirstNane
FROM Employees
JOIN Managers m ON e.ManagerId = m.Id
Note that once you define an alias, you can't use the canonical table name anymore.
SELECT @.Frame, Employees.LName, m.Fname AS ManegerFirstNane
FROM Employees &
JOIN Managers m ON e.ManagerId = m.1d
would throw an error.
Itis worth noting table aliases ~ more formally ‘range variables’ - were introduced into the SQL language to solve
the problem of duplicate columns caused by INNER JOIN. The 1992 SQL standard corrected this earlier design flaw
by introducing NATURAL JOIN (implemented in mySQL, PostgreSQL and Oracle but not yet in SQL Server), the result
of which never has duplicate column names. The above example is interesting in that the tables are joined on
Goalkicker.com = SQL Notes for Professionals a
Scanned with CamScannercolumns with different names (I¢ and ManagerIé) but are not supposed to be joined on the columns with the same
name (LName, FNane), requiring the renaming of the columns to be performed before the join:
SELECT Frame, LName, ManagerFirstName
FROM Employees
NATURAL. JOIN
( SELECT Id AS ManagerId, Fname AS ManagerFirstName
FROM Managers ) m
Note that although an alias/range variable must be declared for the dervied table (otherwise SQL will throw an
error), it never makes sense to actually use tin the query.
Section 6.9: Selecting with more than 1 condition
‘The AND keyword is used to add more conditions to the query.
Name Age Gender
Sam 18 M
John 21M
Bob 22 M
Mary 23 F
SELECT mame FROM persons NHERE gender = 'H' AND age > 20.
This will return:
Name
John
Bob
using 08 keyword
SELECT name FROM persons WHERE gender = “N’ OR age < 26
This will return:
name
sam
John
Bob
‘These keywords can be combined to allow for more complex criteria combinations:
SELECT name
FROM persons
WHERE (gender - 'M’ AND age < 20)
OR (gender = "F’ AND age > 20)
This will return:
name
Sam
Mary
Goalkicker.com = SQL Notes for Professionals 2
Scanned with CamScannerSection 6.10: Selecting without Locking the table
Sometimes when tables are used mostly (or only) for reads, indexing does not help anymore and every little bit
counts, one might use selects without LOCK to improve performance.
SQL Server
SELECT * FROM TableName WITH (nolock)
Mysql
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM TableName.
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ.
Oracle
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM TableName.
pB2
SELECT * FROM TableName WITH UR
where UR stands for "uncommitted read".
If used on table that has record modifications going on might have unpredictable results.
Section 6.11: Selecting with Aggregate functions
Average
The AVG() aggregate function will return the average of values selected.
SELECT AVG(Salary) FROM Employees
‘Aggregate functions can also be combined with the where clause.
SELECT AVG(Salary) FROM Employees where DepartmentId = 1
‘Aggregate functions can also be combined with group by clause.
If employee is categorized with multiple department and we want to find avg salary for every department then we
can use following query.
SELECT AVG(Salary) FROM Employees GROUP BY DepartmentId
Minimum
‘The MIN() aggregate function will return the minimum of values selected.
SELECT MIN(Salary) FROM Employees
Maximum.
‘The MAX() aggregate function will return the maximum of values selected.
SELECT MAK(Salary) FROM Employees
Count
‘The COUNT() aggregate function will return the count of values selected.
SELECT Count() FROM Employees
Itcan also be combined with where conditions to get the count of rows that satisfy specific conditions.
Goalkicker.com = SQL Notes for Professionals B
Scanned with CamScannerSELECT Count() FROM Employees where NanagerId 1S NOT NULL
Specific columns can also be specified to get the number of values in the column. Note that NULL values are not
countes.
Select Count(ManagerId) fron Employees
Count can also be combined with the distinct keyword for a distinct count.
Select Count(DISTINCT DepartmentId) from Employees
sum
‘The sum() aggregate function returns the sum of the values selected for all rows.
SELECT SUM(Salary) FROM Employees
Section 6.12: Select with condition of multiple values from
column
SELECT FROM Cars WHERE status IN ( "Waiting’, ‘Working’ )
This is semantically equivalent to
SELECT = FROM Cars WHERE ( status = ‘Waiting’ OR status = ‘Working’ )
ie. value IN ( ) isa shorthand for disjunction (logical OR).
Section 6.13: Get aggregated result for row groups
Counting rows based on a specific column value:
SELECT category, COUNT(*) AS itemcount
FROM item
GROUP BY category:
Getting average income by departmer
SELECT department, AVG(incone)
FROM employees
GROUP BY department
‘The important thing is to select only columns specified in the GROUP BY clause or used with aggregate functions,
‘There WHERE clause can also be used with GROUP BY, but WHERE filters out records before any grouping is done:
SELECT department, AVG(ineone)
FROM employees
WHERE department <> ‘ACCOUNTING’
GROUP BY department
Hf you need to filter the results after the grouping has been done, e.g, to see only departments whose average
income is larger than 1000, you need to use the HAVING clause:
SELECT department, AVG(incone)
FROM employees
WHERE department <> ‘ACCOUNTING’
GROUP BY department
HAVING avg(income) > 1000;
Goalkicker.com = SQL Notes for Professionals 2
Scanned with CamScannerSection 6.14: Selection with sorted Results
SELECT * FROM Employees ORDER BY LName
This statement will return all the columns from the table Employees.
Id FName LName PhoneNumber
2 John Johnson 2468101214
1 James Smith 1234567890
3 Michael Williams 1357911131
SELECT * FROM Employees ORDER BY LName DESC
or
SELECT * FROM Employees ORDER BY LName ASC
This statement changes the sorting direction.
One may also specify multiple sorting columns. For example:
SELECT * FROM Employees ORDER BY LName ASC, FName ASC
This example will sort the results first by LName and then, for records that have the same LNane, sort by FName. This,
will give you a result similar to what you would find in a telephone book.
In order to save retyping the column name in the ORDER BY clause, its possible to use instead the column's
number. Note that column numbers start from 1.
SELECT Id, FName, LName, PhoneNunber FROM Employees ORDER BY 3
‘You may also embed a CASE statement in the ORDER BY clause.
SELECT Id, FName, LName, PhoneNumber FROM Employees ORDER BY CASE WHEN LName-'Jones’ THEN @ ELSE 1
END ASC
This will sort your results to have all records with the LName of "Jones" at the top.
Section 6.15: Selecting with null
SELECT Neme FROM Customers WHERE PhoneNunber TS NULL.
Selection with nulls take a different syntax. Don't use =, use IS NULL or TS NOT NULL instead,
Section 6.16: Select distinct (unique values only)
‘SELECT DISTINCT ContinentCode
FROM Countries
This query will return all DISTINCT (unique, different) values from Cont inentCode column from Countries table
Continentcode
oc
fu
Goalkicker.com = SQL Notes for Professionals BS
Scanned with CamScannerAS
NA
AF
LFiddle Dem
Section 6.17: Select rows from multiple tables
‘SELECT *
FROM
tablet
‘table2
‘SELECT
tablet .columnt
table! .column2,
table2.columnt
FROM
tablet
table
This is called cross product in SQL itis same as cross product in sets
‘These statements return the selected columns from multiple tables in one query.
‘There is no specific relationship between the columns returned from each table.
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
26Chapter 7: GROUP BY
Results of a SELECT query can be grouped by one or more columns using the GROUP BY statement: all results with
the same value in the grouped columns are aggregated together. This generates a table of partial results, instead of
one result. GROUP BY can be used in conjunction with aggregation functions using the HAVING statement to define
how non-grouped columns are aggregated.
Section 7.1: Basic GROUP BY example
It might be easier if you think of GROUP BY as “for each" for the sake of explanation. The query below:
SELECT EmpID, SUM (WonthlySalary)
FROM Employee
GROUP BY EmpID
is saying:
"Give me the sum of MonthlySalary's for each EmpiD"
So if your table looked like this:
| EnpID|MonthtySatary|
|1 [200 \
[2 [300 1
Result:
| 1/200)
| 2/309)
‘Sum wouldn't appear to do anything because the sum of one number is that number. On the other hand ifit looked
like this:
| EnpID|MonthlySatary|
| |200 I
j1 [300 i
|2 |300 i
Result:
Goalkicker.com = SQL Notes for Professionals 7
Scanned with CamScanner{2/580
(2/300)
‘Then it would because there are two EmpID 1's to sum together.
Section 7.2: Filter GROUP BY results using a HAVING clause
AHAVING clause filters the results of a GROUP BY expression. Note: The following examples are using the Library
example database.
Examples:
Return all authors that wrote more than one book (live example).
SELECT
ald
a.Nane,
COUNT(*) Booksritten
FROM BooksAuthors ba
INNER JOIN Authors a ON a.id - ba.authorid
GROUP BY
a.td
a.Nane
HAVING COUNT(+) > 1 equals to HAVING BooksWritten > 1
Return all books that have more than three authors (live example).
‘SELECT
b.Id
b.Title,
COUNT(*) NumberOfAuthors
FROM BooksAuthors ba
INNER JOIN Books b ON b.id = ba.bookid
GROUP BY
b.Id
b.Title
HAVING COUNT(+) > 3. ~~ equals to HAVING NumberOfAuthors > 3
Section 7.3: USE GROUP BY to COUNT the number of rows for
each unique entry in a given column
Let's say you want to generate counts or subtotals for a given value in a column.
Given this table, 'Westerosians':
Name GreatHousedllegience
Arya — Stark
Cercei_Lannister
Myrcella Lannister
Yara Greyjoy
Catelyn Stark
Goalkicker.com = SQL Notes for Professionals 28
Scanned with CamScannerSansa Stark
Without GROUP BY, COUNT will simply return a total number of rows:
SELECT Count(*) Nunber_of Westerosians
FROM Westerosians
returns...
Number of Westerosians
6
But by adding GROUP BY, we can COUNT the users for each value in a given column, to return the number of
people ina given Great House, say:
SELECT GreatHouseAllegience House, Count(*) Number_of_Westerosians
FROM Westerosians
GROUP BY GreatHouseAllegience
returns...
House Number of Westerosians
Stark = 3
Greyjoy 1
Lannister 2
It's common to combine GROUP BY with ORDER BY to sort results by largest or smallest category:
SELECT GreatHouseAllegience House, Count(+) Number_of Mesterosians
FROM Westerosians
GROUP BY GreatHouseAllegience
ORDER BY Nunber_of_Westerosians Desc
returns...
House Number_of Westerosians
stark = 3
Lannister 2
Greyjoy 1
Section 7.4: ROLAP aggregation (Data Mining)
Description
‘The SQL standard provides two additional aggregate operators. These use the polymorphic value "ALL" to denote
the set of all values that an attribute can take. The two operators are:
‘with data cube that it provides all possible combinations than the argument attributes of the clause.
‘+ with roll up that it provides the aggregates obtained by considering the attributes in order from left to
right compared how they are listed in the argument of the clause.
SQL standard versions that support these features: 1999,2003,2006,2008,2011.
Examples
Goalkicker.com = SQL Notes for Professionals 2
Scanned with CamScannerConsider this table:
Food Brand Total amount
Pasta Brand1 100
Pasta Brand2 250
Pizza Brand2 300
With cube
select Food, Brand, Total_amount
from Table
group by Food, Brand, Total_anount with cube
Food Brand Total_amount
Pasta Brand1 100
Pasta Brand2 250
Pasta ALL 350
Pizza Brand2 300
Pizza ALL 300
ALL Brand? 100
ALL Brand? 550
ALL ALL 650
With roll up
select Food, Brand, Total_emount
from Table
group by Food, Brand, Total_anount with roll up
Food Brand Total amount
Pasta Brand’ 100
Pasta Brand2 250
Pizza Brand2 300
Pasta ALL 350
Pizza ALL 300
ALL ALL 650
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
30Chapter 8: ORDER BY
Section 8.1: Sorting by column number (instead of name)
You can use a column's number (where the leftmost column is '1'} to indicate which column to base the sort on,
instead of describing the column by its name.
Pro: If you think it’s likely you might change column names later, doing so won't break this code.
Con: This will generally reduce readability of the query It's instantly clear what ‘ORDER BY Reputation’ means, while
‘ORDER BY 14’ requires some counting, probably with a finger on the screen.)
This query sorts result by the info in relative column position 3 from select statement instead of column name
Reputation.
SELECT DisplayName, JoinDate, Reputation FROM Users ORDER BY 3
DisplayName JoinDate Reputation
Community 2008-09-15 4
Jarrod Dixon 2008-10-03 11739
Geoff Dalgas 2008-10-03 12567
Joel Spolsky 2008-09-16 25784
Jeff Atwood 2008-09-16 37628
Section 8.2: Use ORDER BY with TOP to return the top x rows
based on a column's value
In this example, we can use GROUP BY not only determined the sort of the rows returned, but also what rows are
returned, since we're using TOP to limit the result set
Let's say we want to return the top 5 highest reputation users from an unnamed popular Q&A site.
Without ORDER BY
This query returns the Top 5 rows ordered by the default, which in this case is “id, the first column in the table
(even though it's not a column shown in the results)
SELECT TOP 5 DisplayName, Reputation
FROM Users
returns...
DisplayName Reputation
Community 1
Geoff Dalgas 12567
Jarrod Dixon 11739
Jeff wood 37628
Joel Spolsky 25784
With ORDER BY
SELECT TOP 5 DisplayName, Reputation
FROM Users
Goalkicker.com = SQL Notes for Professionals a
Scanned with CamScannerORDER BY Reputation desc
returns.
DisplayName Reputation
JonSkeet 865023
Darin Dimitrov 661741
Balusc 650237
Hans Passant 625870
MarcGravell 601636
Remarks
Some versions of SQL (such as MySQU) use a LIMIT clause at the end of a SELECT, instead of ToP at the beginning,
for example:
SELECT DisplayName, Reputation
FROM Users
ORDER BY Reputation DESC
LamiT 5
Section 8.3: Customizeed sorting order
To sort this table Employee by department, you would use ORDER BY Department. However, if you want a different
sort order that is not alphabetical, you have to map the Department values into different values that sort correctly;
this can be done with a CASE expression:
Name Department
Hasan IT
Yusuf HR
Hillary HR
Joe iT
Merry HR
Ken Accountant
SELECT *
FROM Enployee
ORDER BY CASE Department
WHEN "HR THEN 1
WHEN ‘Accountant’ THEN 2
ELSE 3
END
Name Department
Yusuf HR
Hillary HR
Merry HR
Ken Accountant
Hasan IT
Joe iT
Section 8.4: Order by Alias
Due to logical query processing order, alias can be used in order by.
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
32SELECT DisplayNeme, JoinDate as jd, Reputation es rep
FROM Users
ORDER BY jd, rep
‘And can use relative order of the columns in the select statement .Consider the same example as above and
instead of using alias use the relative order like for display name itis 1 , for Jd itis 2 and so on.
SELECT DisplayName, JoinDate as jd, Reputation es rep
FROM Users
ORDER BY 2, 3
Section 8.5: Sorting by multiple columns
SELECT DisplayName, JoinDate, Reputation FROM Users ORDER BY JoinDate, Reputation
DisplayName JoinDate Reputation
Community 2008-09-15 1
Jeff Atwood 2008-09-16 25784
Joel Spolsky 2008-09-16 37628
Jarrod Dixon 2008-10-03 11739
Geoff Dalgas 2008-10-03 12567
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
33Chapter 9: AND & OR Operators
Section 9.1: AND OR Example
Have a table
Name Age City
Bob 10 Paris
Mat 20 Berlin
Mary 24 Prague
select Name from table where Age>10 AND City-'Prague
Gives
Name
Mary
select Name from table where Age-10 OR City-'Pregue’
Gives
Name
Bob
Mary
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
34Chapter 10: CASE
‘The CASE expression is used to implement if-then logic.
Section 10.1: Use CASE to COUNT the number of rows ina
column match a condition
Use Case
CASE can be used in conjunction with SUN to return a count of only those items matching a pre-defined condition.
(This is similar to COUNTIF in Excel.)
‘The trick is to return binary results indicating matches, so the "1"s returned for matching entries can be summed
for a count of the total number of matches.
Given this table ItenSates, let's say you want to learn the total number of items that have been categorized as
"Expensive":
Id Itemid Price PriceRating
1100 34.5 EXPENSIVE
2145 23 CHEAP
3100 34.5 EXPENSIVE
4100 345. EXPENSIVE
5145 10 AFFORDABLE
Query
SELECT
‘COUNT(Id) AS TtensCount
SUM (CASE
WHEN PriceRating - "Expensive" THEN 1
ELSE @
END
) AS ExpensiveltemsCount
FROM ItemSales
Results:
ItemsCount ExpensiveltemsCount
5 3
Alternative:
SELECT
COUNT(Td) as TtemsCount
SUK (
CASE PriceRating
WHEN ‘Expensive’ THEN 1
ELSE @
END
AS ExpensiveTtemsCount
FROM TtemSales
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
35Section 10.2: Searched CASE in SELECT (Matches a boolean
expression)
‘The searched CASE returns results when a boolean expression is TRUE.
(This differs from the simple case, which can only check for equivalency with an input)
SELECT Id, Itemld, Price
CASE WHEN Price < 18 THEN ‘CHEAP’
WHEN Price < 28 THEN ‘AFFORDABLE:
ELSE ' EXPENSIVE
END AS PriceRating
FROM TtenSales
Id Itemid Price PriceRating
1100 34.5. EXPENSIVE
2145 23 CHEAP
3100 345 EXPENSIVE
4100 345 EXPENSIVE
5145 10 AFFORDABLE
Section 10.3: CASE in a clause ORDER BY
We can use 1,2,3..to determine the type of order:
SELECT * FROM DEPT
ORDER BY
CASE DEPARTMENT
WHEN “MARKETING’ THEN 1
WHEN ‘SALES’ THEN 2
WHEN ‘RESEARCH’ THEN 2
WHEN “INNOVATION’ THEN 4
ELSE 5
END
crty
ID REGION —ciTY DEPARTMENT EMPLOYEES NUMBER
12. New England Boston MARKETING 8
15 West San Francisco MARKETING 2
9 Midwest Chicago SALES 8
14 Mid-Atlantic New York SALES 12
5 West Los Angeles RESEARCH "
10 Mid-Atlantic Philadelphia RESEARCH 3
4 Midwest Chicago INNOVATION "
2 Midwest Detroit. ©“ HUMAN RESOURCES 9
Section 10.4: Shorthand CASE in SELECT
CASE's shorthand variant evaluates an expression (usually a column) against a series of values. This variant is a bit
shorter, and saves repeating the evaluated expression over and over again. The ELSE clause can still be used,
though:
SELECT Id, ItemId, Price
CASE Price WHEN 5 THEN ‘CHEAP’
WHEN 15 THEN "AFFORDABLE"
Goalkicker.com = SQL Notes for Professionals 36
Scanned with CamScannerELSE " EXPENSIVE"
END as PriceRating
FROM ItemSales
Aword of caution. It's important to realize that when using the short variant the entire statement is evaluated at
each WHEN, Therefore the following statement:
SELECT
CASE ABS(CHECKSUM(NEWID())) % 4
WHEN @ THEN ‘Dr’
WHEN 1 THEN “Master
WHEN 2 THEN °Mr
WHEN 3 THEN “Hrs”
END
may produce @ NULL result, That is because at each WHEN NEWIO() is being called again with a new result. Equivalent
SELECT
CASE
WHEN ABS(CHECKSUN(NEWID())) % ‘or
WHEN ABS(CHECKSUM(NEWID())) % ‘Master’
WHEN ABS(CHECKSUM(NEWID())) % “Me
WHEN ABS(CHECKSUM(NEWTD())) % “Mrs
END
‘Therefore it can miss all the WHEN cases and result as NULL.
Section 10.5: Using CASE in UPDATE
sample on price increases:
UPDATE TtemPrice
SET Price = Price +
(CASE ItemId
WHEN 1 THEN 1.05
WHEN 2 THEN 1.10
WHEN 3 THEN 1.15
ELSE 1.00
END
Section 10.6: CASE use for NULL values ordered last
jepresenting the known values are ranked first, 1' representing the NULL values are sorted by the
SELECT 1D
REGION
crTy
DEPARTMENT.
EMPLOYEES. NUMBER
FROM DEPT
ORDER BY
CASE WHEN REGION IS NULL THEN 1
ELSE @
END
REGION
Goalkicker.com = SQL Notes for Professionals 7
Scanned with CamScannerID REGION city DEPARTMENT EMPLOYEES. NUMBER
10 Mid-Atlantic Philadelphia RESEARCH 3
14 Mid-Atlantic New York SALES 12
9 Midwest Chicago SALES a
12 New England Boston MARKETING 3
5 West Los Angeles RESEARCH "
15 NULL ‘san Francisco MARKETING 12
4 NULL Chicago INNOVATION "
2 NULL Detroit HUMAN RESOURCES 9
Section 10.7: CASE in ORDER BY clause to sort records by
lowest value of 2 columns
Imagine that you need sort records by lowest value of either one of two columns. Some databases could use a non-
aggregated MIN() or LEAST() function for this... ORDER BY MIN(Date1, Date2)), but in standard SQL, you have
to use a CASE expression.
‘The CASE expression in the query below looks at the Dete1 and Date2 columns, checks which column has the lower
value, and sorts the records depending on this value.
Sample data
Id Datet —_Datez
1 2017-01-01 2017-01-31
2 2017-01-31 2017-01-03
3 2017-01-31 2017-01-02
4 2017-01-06 2017-01-31
5 2017-01-31 2017-01-05
6 2017-01-04 2017-01-31
Query
SELECT Id, Date1, Date2
FROM YourTable
ORDER BY CASE
WHEN COALESCE (Date1, '1753-01-01') < COALESCE(Date2, '1753-@1-1") THEN Datet
ELSE Date?
END
Results
Id Datet —_Date2
1 2017-01-01 2017-01-31
3 2017-01-31 2017-01-02
2 2017-01-31 2017-01-03
6 2017-01-04 2017-01-31
5 2017-01-31 2017-01-05
4 2017-01-06 2017-01-31
Explanation
‘As you see row with Td = 1 is first, that because Date1 have lowest record from entire table 2617-61-01, row where
Td = 3is second that because Date? equals to 2017-61-82 that is second lowest value from table and so on.
Sowe have sorted records from 2617-01-61 to 2617-61-06 ascending and no care on which one column Date? or
Date? are those values.
Goalkicker.com = SQL Notes for Professionals 38
Scanned with CamScannerChapter 11: LIKE operator
Section 11.1: Match open-ended pattern
‘The % wildcard appended to the beginning or end (or both) of a string will allow 0 or more of any character before
the beginning or after the end of the pattern to match.
Using "%' in the midale will allow 0 or more characters between the two parts of the pattern to match.
We are going to use this Employees Table:
IdFName LName PhoneNumber Managerid Departmentid Salary Hire date
1 John Johnson 24681012141 1 400 23-03-2005
2 Sophie Amudsen 2479700211 400 11-01-2010
3 Ronny Smith 2462544026 600 06-08-2015
4 Jon Sanchez 2454124602 400 23-03-2005
1
2
1
5 Hilde Knag 24680219112 800 07-01-2000
Following statement matches for all records having FName containing string ‘on’ from Employees Table.
SELECT * FROM Employees WHERE FName LIKE "on"
Id FName LName PhoneNumber Managerld Departmentid Salary Hire date
3 Ronny Smith 2462544026 2 1 600 06-08-2015
4 Jon Sanchez 24541246021 1 400 23-03-2005
Following statement matches all records having PhoneNumber starting with string '246' from Employees.
SELECT * FROM Employees WHERE PhoneNunber LIKE ‘246%
Id FName LName PhoneNumber Managerid Departmentid Salary Hire_date
1 John Johnson 2468101214 1 400 23-03-2005
3 Ronny Smith 2462544026 2 1 600 06-08-2015
5 Hilde Knag 2468021911 2 1 800 01-01-2000
Following statement matches all records having PhoneNumber ending with string "11' from Employees.
SELECT « FROM Employees WHERE PhoneNunber LIKE *%11°
idFName LName PhoneNumber Managerid Departmentid Salary Hire date
2 Sophie Amudsen 24781002111 1 400 17-01-2010
5 Hilde Knag 24680219112 1 800 01-01-2000
All records where Fname 3rd character is 'n’ from Employees.
SELECT * FROM Employees WHERE FName LIKE
(two underscores are used before 'n’ to skip first 2 characters)
Id FName LName PhoneNumber Managerid Departmentid Salary Hire date
3 Ronny Smith 2462544026 2 1 600 06-08-2015
4 Jon — Sanchez 24541246021 1 400 23-03-2005
Goalkicker.com - SQL Notes for Professionals 9
Scanned with CamScannerSection 11.2: Single character match
To broaden the selections of a structured query language (SQL-SELECT) statement, wildcard characters, the percent
sign (96) and the underscore (), can be used.
The _ (underscore) character can be used as a wildcard for any single character in a pattern match.
Find all employees whose Fame start with ' and end with 'n’ and has exactly 3 characters in Frame.
SELECT * FROM Employees WHERE FName LIKE *j_n’
_ (underscore} character can also be used more than once as a wild card to match patterns.
For example, this pattern would match "jon", jan", "jen", etc.
These names will not be shown "jn’,"john’,"jordan’, "justin", "jason", julian’, ‘jillian’, “joann” because in our query
one underscore is used and it can skip exactly one character, so result must be of 3 character Fname,
For example, this pattern would match "Last, "LoSt’, "HaLt", etc.
SELECT * FROM Employees WHERE FName LIKE "_A_T
Section 11.3: ESCAPE statement in the LIKE-query
If you implement a text-search as LTKE-query, you usually do it like this:
SeLecT «
FROM T_Whatever
WHERE SomeField LIKE CONCAT(*%', @in_SearchText, ‘'%')
However, (apart from the fact that you shouldn't necessarely use LIKE when you can use fulltext-search) this
creates a problem when somebody inputs text like "50%" or "a_b"
So (instead of switching to fulltext-search), you can solve that problem using the LIKE-escape statement:
SELECT +
FROM T_Whatever
WHERE SomeField LIKE CONCAT(‘%', @in_SearchText, '%') ESCAPE ‘\'
‘That means \ will now be treated as ESCAPE character. This means, you can now just prepend \ to every character
in the string you search, and the results will start to be correct, even when the user enters a special character like %
or.
eg.
string stringToSearch = “abe def 58%
string newString = **
foreach(char ¢ in stringToSearch)
newString += @"\" + ¢
sqlOnd.Parameters.Add(*@in_SearchText", newString)
/ instead of sqlCnd Parameters Add("@in_SearchText”, stringToSearch)
Note: The above algorithm is for demonstration purposes only. It will not work in cases where 1 grapheme consists
out of several characters (utf-8), eg. string stringToSearch - “Les Mise\u@301rables" ; You'll need to do this
Goalkicker.com = SQL Notes for Professionals 40
Scanned with CamScannerfor each grapheme, not for each character. You should not use the above algorithm if you're dealing with
Asian/East-Asian/South-Asian languages. Or rather, if you want correct code to begin with, you should just do that
for each graphemeCluster.
See also ReverseString, a C# interview-question
Section 11.4: Search for a range of characters
Following statement matches all records having FName that starts with a letter from A to F from Employees Table.
‘SELECT » FROM Employees WHERE FName LIKE ‘[A-F]%'
Section 11.5: Match by range or set
Match any single character within the specified range (e.g.: (a-f]) or set (e.g.: | abcde).
This range pattern would match "gary" but not "mary’:
SELECT * FROM Employees WHERE FName LIKE '[a-glery’
This set pattern would match "mary" but not "gary":
‘SELECT * FROM Employees WHERE Frame LIKE ‘(Imnop]ary’
‘The range or set can also be negated by appending the 4 caret before the range or set:
This range pattern would not match "gary” but will match "mary":
SELECT * FROM Employees WHERE FName LIKE ‘[*e-glary®
This set pattern would not match "mary" but wil match'gary"
SELECT * FROM Employees WHERE Frame LIKE '[*Ilnnop]ary'
: Wildcard characters
Section 11.
wildcard characters are used with the SQL LIKE operator. SQL wildcards are used to search for data within a table.
Wildcards in SQL are:%, _, [charlist], [*charlist]
‘%- A substitute for zero or more characters
Eg: //selects all customers with a City starting with “Lo
SELECT * FROM Customers
WHERE City LIKE ‘Lo®
/eelects all customers with a City conteining the pattern “es”
SELECT * FROM Customers
WHERE City LIKE ‘Sest’;
Asubstitute for a single character
Eg://selects all customers with a City starting with any character, followed by “erlin®
SELECT * FROM Customers
Goalkicker.com = SQL Notes for Professionals a
Scanned with CamScannerWHERE City LIKE *
Icharlist] - Sets and ranges of characters to match
Eg://selects all customers with a City starting with "a", “
‘SELECT * FROM Customers
WHERE City LIKE ‘[od1]%"
or "1
//selects all customers with a City starting with ‘a
SELECT » FROM Customers
WHERE City LIKE ‘[a-c]s*
[charlist] - Matches only a character NOT specified within the brackets
Eg://selects all customers with a City starting with a character that is not
‘SELECT + FROM Custoners
WHERE City LIKE '[*ap1]%";
SELECT * FROM Customers
WHERE City NOT LIKE ‘[apl]®’ and city like
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
42Chapter 12: IN clause
Section 12.1: Simple IN clause
To get records having any of the given sds
select *
from products
where id in (1,8,3)
The query above is equal to
select *
from products
where id = 1
Section 12.2: Using IN clause with a subquery
‘SELECT +
FROM customers
WHERE id IN (
SELECT DISTINCT customer_id
FROM orders
)
The above will give you all the customers that have orders in the system.
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
aChapter 13: Filter results using WHERE and
HAVING
Section 13.1: Use BETWEEN to Filter Results
‘The following examples use the Item Sales and Customers sample databases.
Note: The BETWEEN operator is inclusive.
Using the BETWEEN operator with Numbers:
SELECT = From ItenSales
WHERE Quantity BETWEEN 18 AND 17
This query will return all TtemSales records that have a quantity that is greater or equal to 10 and less than or equal
to 17. The results will look like:
Id SaleDate Itemid Quantity Price
1 2013-07-01 100 10 345
4 2013-07-23100 15 345
5 2013-07-24145 10 345
Using the BETWEEN operator with Date Values:
SELECT * From ItenSales
WHERE SaleDate BETWEEN '2013-@7-11' AND '2073-05-24"
This query will return all Ttemsales records with a SaleDate that is greater than or equal to July 11, 2013 and less,
than or equal to May 24, 2013,
Id SaleDate Itemid Quantity Price
3 2013-07-11100 20 345
4 2013-07-23100 15 345
5 2013-07-24145 10 345
When comparing datetime values instead of dates, you may need to convert the datetime values into a
date values, or add or subtract 24 hours to get the correct results.
Using the BETWEEN operator with Text Values:
SELECT Id, FName, LName FROM Customers
WHERE LName BETWEEN 'D' AND ‘L"
Live example: SOL fiddle
This query will return all customers whose name alphabetically falls between the letters ‘D' and ‘L’ In this case,
Customer #1 and #3 will be returned, Customer #2, whose name begins with a'M' will not be included.
Id FName LName
Goalkicker.com - SQL Notes for Professionals a
Scanned with CamScanner1 William Jones
3 Richard Davis
Section 13.2: Use HAVING with Aggregate Functions
Unlike the WHERE clause, HAVING can be used with aggregate functions.
‘An aggregate function is a function where the values of multiple rows are grouped together as input on
certain criteria to form a single value of more significant meaning or measurement (Wikipedia
Common aggregate functions include COUNT(), SUM(), MIN(), and MAX(),
This example uses the Car Table from the Example Databases.
SELECT CustomerId, COUNT(Ed) AS [Number of Cars
FROM Cars
GROUP BY CustomerId
HAVING COUNT(Id) > 1
This query will return the CustomerId and Number of Cars count of any customer who has more than one car. In
this case, the only customer who has more than one car is Customer #1.
‘The results will look like:
Customerid Number of Cars
1 2
Section 13.3: WHERE clause with NULL/NOT NULL values
SELECT
FROM Employees
WHERE ManagerTd IS NULL
This statement will return all Employee records where the value of the Menager Id column is NULL.
The result will be:
Id FName —LName_—-PhoneNumber ManagerId_—_DepartmentId
1 James Smith 1234567890 NULL 1
SELECT
FROM Employees
WHERE ManagerId IS NOT NULL
This statement will return all Employee records where the value of the MenagerTd is not NULL.
The result will be:
Id Fame LWame PhoneNumber ManagerId_DepartmentId
2 ohn Johnson 24681012141 a
3 Michael = Williams 13579111311 ZI
4 Johnathon Smith 12121212122 1
Goalkicker.com = SQL Notes for Professionals 5
Scanned with CamScannerNote: The same query will not return results if you change the WHERE clause to WHERE ManagerTd = NULL or WHERE
ManagerIé <> NULL.
Section 13.4: Equality
SELECT + FROM Employees
This statement will return all the rows from the table Employees.
Id Name LName —PhoneNumber ManagerId Departmentid Salary Hire date
Createddate ModifiedDate
1 James Smith 1234567899 NULL. 1 1908 61-01-2002 91-01-2902
61-01-2002
2 John Johnson 24681012141 1 400 23-03-2005 23-03-2005
61-01-2002
3 Michael Williams 1357911131 1 2 600 © 12-05-2009 12-95-2009
NULL.
4 Johnathon Smith 12121212122 1 500 24-07-2016 24-87-2016
1-01-2002
Using a WHERE at the end of your SELECT statement allows you to limit the returned rows to a condition. In this case,
where there is an exact match using the = sign:
SELECT * FROM Employees WHERE DepartmentId - 1
Will only return the rows where the DepartmentId is equal to 1:
Id FName LName —PhoneNumber ManagerId DepartmentId Salary Hire date
CreatedDate ModifiedDate
1 James Smith 1234567890 NULL. 1 1998 61-61-2802 61-01-2082
01-61-2002
2 John Johnson 2468101214 1 1 400 23-03-2005 23-03-2005
61-01-2902
4 Johnathon Smith 12121212122 1 500 24-07-2016 24-07-2016
1-61-2002
Section 13.5: The WHERE clause only returns rows that match
its criteria
Steam has a games uncer $10 section of their store page. Somewhere deep in the heart of their systems, there's
probably a query that looks something like:
SELECT «
FROM Items
WHERE Price < 10
Section 13.6: AND and OR
‘You can also combine several operators together to create more complex WHERE conditions. The following examples
use the Employees table:
Id Flame LName_—-PhoneNumber ManagerId Departmentid Salary Hire date
Goalkicker.com = SQL Notes for Professionals 46
Scanned with CamScannerCreateddate Modifieddate
1 James Smith 1234567890 NULL 1 1008 61-01-2002 01-01-2002
1-61-2002
2 John Johnson 24681012141 1 400 23-63-2005 23-03-2005
1-01-2002
3 Michael Williams 1357911131 1 2 600 12-65-2009 12-85-2009
NULL
4 Johnathon Smith 12121212122 1 500 24-07-2016 24-07-2016
1-01-2002
AND
SELECT * FROM Employees WHERE DepartmentId - 1 AND ManagerId - 1
Will return:
Id Flame LName —PhoneNumber ManagerId Departmentid Salary Hire date
Createddate ModifiedDate
2 John Johnson 24681012141 1 400 23-03-2005 23-03-2005
61-61-2002
OR
SELECT = FROM Employees WHERE DepartmentId - 2 OR ManagerId - 2
Will return:
Id Fame LName —PhoneNumber ManagerId Departmentid Salary Hire date
Createddate ModifiedDate
3 Michael Williams 1357911231 1 2 600 © 12-05-2009 12-85-2009
NULL.
4 Johnathon Smith 12121212122 1 500 24-07-2016 24-07-2016
61-61-2902
all 13.7: Use IN to return rows with a value contained in a
ist
This example uses the Car Table from the Example Databases.
SELECT *
FROM Cars
WHERE TotalCost IN (100, 200, 360)
This query will return Car #2 which costs 200 and Car #3 which costs 100. Note that this is equivalent to using
multiple clauses with og, e.g.
SELECT *
FROM Cars
WHERE TotalCost = 19 OR TotalCost = 200 OR TotelCost = 308
Section 13.8: Use LIKE to find matching strings and substrings
See full documentation on LIKE operator.
Goalkicker.com - SQL Notes for Professionals 7
Scanned with CamScannerThis example uses the Employees Table from the Example Databases.
‘SELECT +
FROM Employees
WHERE FName LIKE ‘John’
This query will only return Employee #1 whose first name matches ‘John’ exactly.
SELECT *
FROM Employees
WHERE FName Like ‘John’s’
Adding % allows you to search for a substring:
‘+ John’ - will return any Employee whose name begins with john’, followed by any amount of characters
‘+ John - will return any Employee whose name ends with John’, proceeded by any amount of characters
‘+ John’s - will return any Employee whose name contains John’ anywhere within the value
In this case, the query will return Employee #2 whose name is John’ as well as Employee #4 whose name is
‘Johnathon’
Section 13.9: Where EXISTS
Will select records in TableName that have records matching in TableName1.
SELECT * FROM TableName t WHERE EXISTS (
SELECT 1 FROM TableName! ti where t.Id = t1.Id)
Section 13.10: Use HAVING to check for multiple conditions in a
group
Orders Table
Customerid Productid Quantity Price
1 2 5 100
1 3 2 200
1 4 1 500
2 1 4 50
3 5 6 700
To check for customers who have ordered both - ProductID 2 and 3, HAVING can be used
select custonerId
fron orders
where productID in (2,3)
group by customerId
having count (distinct productID) = 2
Return value:
customerid
1
‘The query selects only records with the productiDs in questions and with the HAVING clause checks for groups
Goalkicker.com = SQL Notes for Professionals 48
Scanned with CamScannerhaving 2 productids and not just one.
Another possibility would be
select custonerId
fron orders
group by customerId
having sum(case when productID
and sum(case when productID
2 then 1 else @ end) > @
3 then 1 else @ end) > a
This query selects only groups having at least one record with productlD 2 and at least one with productiD 3.
Goalkicker.com - SQL Notes for Professionals
Scanned with CamScanner
aChapter 14: SKIP TAKE (Pagination)
Section 14.1: Limiting amount of results
ISO/ANSI SQL:
SELECT * FROM TebleName FETCH FIRST 20 ROWS ONLY
MySQL; PostgreSQL; SQLite:
SELECT + FROM TableName LIMIT 20
Oracle:
‘SELECT Id
colt
FROM (SELECT Id.
colt
row.number() over (order by Id) RowNumber
FROM TableNane)
WHERE RowNumber <= 26
SQL Server:
SELECT TOP 20 +
FROM dbo. (Sale)
Section 14.2: Skipping then taking some results (Pagination)
ISO/ANSI SQL:
SELECT Id, colt
FROM TableName
‘ORDER BY Id
OFFSET 20 ROWS FETCH NEXT 26 ROWS ONLY
MysQl:
SELECT * FROM TableName LIMIT 20, 20; -- offset, limit
Oracle; SQL Server:
SELECT Id
colt
FROM (SELECT Id
col
row.number() over (order by I¢) RowNumber
FROM TableName)
WHERE RowNumber BETWEEN 21 AND 40
PostgreSQL; SQLite:
SELECT * FROM TableName LIMIT 26 OFFSET 20
Goalkicker.com = SQL Notes for Professionals 50
Scanned with CamScannerSection 14.3: Skipping some rows from result
ISO/ANS! SQL:
SELECT 14, colt
FROM TableNne
ORDER BY Id
OFFSET 20 ROWS
MySQl:
SELECT * FROM TableName LIMIT 20, 42424242424242
=- skips 20 for take use very large number that is more than rows in table
Oracle:
SELECT Id
Colt
FROM (SELECT Id,
colt
row.number() over (order by Td) RowNumber
FROM TableNane)
WHERE RowNumber > 20
PostgresQt:
SELECT * FROM TableName OFFSET 20
SQLite:
SELECT + FROM TableName LIMIT -1 OFFSET 20
Goalkicker.com - SQL Notes for Professionals
Scanned with CamScanner
3Chapter 15: EXCEPT
Section 15.1: Select dataset except where values are in this
other dataset
--dataset schenas must be identical
SELECT ‘Datel’ as ‘Colum’ UNION ALL
SELECT ‘1 ‘lumn* UNION ALL
SELECT ‘Date “Column' UNION ALL
SELECT ‘Dated’ as ‘Colum’ UNION ALL
SELECT ‘Dates Column"
EXCEPT
SELECT ‘Date3' as ‘Colu
=-Returns Datal, Data2, Dates, and Datas
Goalkicker.com - SQL Notes for Professionals
Scanned with CamScanner
52Chapter 16: EXPLAIN and DESCRIBE
Section 16.1: EXPLAIN Select query
‘An Explein infront of a select query shows you how the query will be executed, This way you to see if the query
uses an index or if you could optimize your query by adding an index.
Example query:
explain select + from user join data on user test ~ data. fk_user
Example result:
id select_type table type possible_keys key key_len ref rows Extra
a SINPLE user index test test 5 (mW) 1 Using where; Using
index
1 SIMPLE data ret fkuser Thuser 5 user.test 1 (null)
on type you see if an index was used, in the column possible_keys you see if the execution plan can choose from
different indexes of if none exists. key tells you the acutal used index. key_len shows you the size in bytes for one
index item. The lower this value is the more index items fit into the same memory size an they can be faster
processed. rows shows you the expected number of rows the query needs to scan, the lower the better.
Section 16.2: DESCRIBE tablename;
DESCRIBE and EXPLAIN are synonyms. DESCRIBE on a tablename returns the definition of the columns.
DESCRIBE tablenone
Exmple Result:
COLUNN_NAME —COLUNN_TYPE TS_NULLABLE —COLUNN_KEY —COLUNN_DEFAULT EXTRA
id ant(11) No. PRI a auto_increment
test varchar(255) YES null)
Here you see the column names, followed by the columns type. It shows if nul1 is allowed in the column and if the
column uses an index. the default value is also displayed and if the table contains any special behavior like an
auto_inerenent.
Goalkicker.com = SQL Notes for Professionals 33
Scanned with CamScannerChapter 17: EXISTS CLAUSE
Section 17.1: EXISTS CLAUSE
Customer Table
Id FirstName LastName
1 Ozgur Ozturk
2 Youssef Medi
3 Henry Tai
Order Table
Id Customerid Amount
12 123.50
23 14.80
Get all customers with a least one order
‘SELECT * FROM Customer WHERE EXISTS
‘SELECT * FROM Order WHERE Order. CustomerId-Customer Td
Result
Id FirstName LastName
2 Youssef Medi
3 Henry — Tal
Get all customers with no order
SELECT + FROM Customer WHERE NOT EXISTS (
SELECT * FROM Order WHERE Order CustomerId = Customer Id
Result
Id FirstName LastName
1 Ozgur Ozturk
Purpose
EXISTS, IN and JOTN could sometime be used for the same result, however, they are not equals :
‘* EXISTS should be used to check if a value exist in another table
‘* INshould be used for static list
‘+ JOIN should be used to retrieve data from other(s) table(s)
Goalkicker.com = SQL Notes for Professionals 54
Scanned with CamScannerChapter 18: JOIN
JOIN is a method of combining (joining) information from two tables. The result is a stitched set of columns from
both tables, defined by the join type (INNER/OUTER/CROSS and LEFT/RIGHT/FULL, explained below) and join criteria
(how rows from both tables relate).
Atable may be joined to Itself or to any other table. if information from more than two tables needs to be accessed,
multiple joins can be specified in a FROM clause.
Section 18.1: Self Join
Atable may be joined to itself, with different rows matching each ather by some condition. in this use case, aliases
must be used in order to distinguish the two occurrences of the table
In the below example, for each Employee in the example database Employees table, a record is returned containing
the employee's first name together with the corresponding first name of the employee's manager. Since managers
are also employees, the table is joined with itself:
SELECT
e.FName AS “Employee”,
m.FName AS “Manager
FROM
Employees e
JOIN
Employees m
ON e.ManagerTd = m.I¢
This query will return the following data:
Employee Manager
John James
Michael James
Johnathon john
So how does this work?
‘The original table contains these records:
IdFName LName PhoneNumber Managerid Departmentid Salary HireDate
1 James Smith 1234567890 NULL 1 1000 01-01-2002
2 John Johnson 24681012141 1 400 23-03-2005
3 Michael Williams 13579111311 2 600 12-05-2009
4 Johnathon Smith 1212121212 2 1 500 24-07-2016
The first action is to create a Cartesian product of all records in the tables used in the FROM clause. In this case it's,
the Employees table twice, so the intermediate table will look lke this (Ive removed any fields not use¢ in this
example):
e.lde.FName e.Managerid m.id m.FName m.Managerld
1 James NULL 1 James = NULL
1 James NULL 2 John 1
1 James NULL 3 Michael 1
Goalkicker.com = SQL Notes for Professionals 55
Scanned with CamScanner1 James NULL 4 Johnathon 2
2 John 1 1 James NULL
2 John 1 2 john 1
2 John 1 3 Michael 1
2 John 4 4 Johnathon 2
3 Michael 1 1 James NULL
3 Michael 1 2 john 1
3 Michael 1 3 Michael 1
3 Michael 1 4 Johnathon 2
4 Johnathon 2 1 James NULL
4 Johnathon 2 2 john 1
4 Johnathon 2 3 Michael 1
4 Johnathon 2 4 Johnathon 2
The next action is to only keep the records that meet the JOIN criteria, so any records where the aliased e table
ManagerId equals the aliased m table Té:
eld eFName e.Managerid m.id m.FName m.Managerid
2 John 1 1 James NULL
3° Michael 1 1 James NULL
4 Johnathon 2 2 John 4
‘Then, each expression used within the SELECT clause is evaluated to return this table’
e.FName m.fName
John James
Michael James
Johnathon John
Finally, column names e. Flame and m.FName are replaced by their alias column names, assigned with the AS
operator:
Employee Manager
John james:
Michael james
Johnathon john
Section 18.2: Differences between inner/outer joins
SQL has various join types to specify whether (non-)matching rows are included in the result: INNER JOIN, LEFT
OUTER JOIN, RIGHT OUTER JOIN, and FULL OUTER JOIN (the INNER and OUTER Keywords are optional). The figure
below underlines the differences between these types of joins: the blue area represents the results returned by the
join, and the white area represents the results that the join will not return.
Goalkicker.com = SQL Notes for Professionals 56
Scanned with CamScannerSELECT cel
FROM Tables A
INNER JOM Tables
ONAkey = Bay
SELECT SELECT tlts>
FROM Table & AG@BB FROM Tables A
ONAley= Bey
SQL
key ONAKey= Bey
WHERE Bley IS NULL WHERE AKey IS NULL
SELECT cfs setscr >
alld. ques bomt enaat at FULL OUTER JOIN Tae B
ON Akey = Bkey SUA ayaa iey
ot cea ers rete Canon stn 3.0 Unported ane wn Ay fs nck
ee incchtovitonmorsnuineca rpisoserrbace (OR Bey NULL
Cross Join SQL Pictorial Presentation (reference) :
‘SELECT * FROM table1 CROSS JOIN table2;
In CROSS JOIN, each row from 1st table joins with all he rows of another table.
IF stable contain x rows and y rows in 2nd one the result set will be x* y rows.
Below are examples from this answer,
For instance there are two tables as below :
Goalkicker-com ~ SQL Notes for Professionals 7
Scanned with CamScannerNote that (1,2) are unique to A, (3,4) are common, and (5,6) are unique to B.
Inner Join
s the intersection of the two tables, ie. the two rows they
An inner join using either of the equivalent queries
have in common:
select + from a INNER JOIN b on a.a - b.b;
select .*,b.* from a,b where a.a = b.b
Left outer joi
Aleft outer join will give all rows in A, plus any common rows in B:
select * from a LEFT OUTER JOIN b on a.a = b.b
Right outer join
Similarly, a right outer join will give all rows in B, plus any common rows in A:
select * from a RIGHT OUTER JOIN b on a.a - b.b:
a
3013
4 14
mult | 5
mult | 6
Full outer join
‘A full outer join will give you the union of A and B, ie. all the rows in A and all the rows in B. if something in A
doesn't have a corresponding datum in B, then the B portion is null, and vice versa.
select + from a FULL OUTER JOIN b on a.a = b.b
Goalkicker.com = SQL Notes for Professionals 58
Scanned with CamScannerSection 18.3: JOIN Terminology: Inner, Outer, Semi, Anti..
Let's say we have two tables (A and B) and some of their rows match (relative to the given JOIN condition, whatever
it may be in the particular case):
Goalkicker.com - SQL Notes for Professionals
Scanned with CamScanner
59Table A Table B
ANTI
OUTER
INNER
YANNI
YaLNoO
ILNV
SEMI SEMI
LEFT RIGHT
FULL
We can use various join types to include or exclude matching or non-matching rows from either side, and correctly
name the join by picking the corresponding terms from the diagram above.
‘The examples below use the following test data:
CREATE TABLE A (
X varchar (255) PRIMARY KEY
Goalkicker.com = SQL Notes for Professionals 60
Scanned with CamScanner)
CREATE TABLE B (
Y varchar (255) PRIMARY KEY
5
INSERT INTO A VALUES
(amy)
(‘John’)
(‘Lisa’),
(‘Marco’),
("Phat")
INSERT INTO B VALUES
(‘Lisa
(*Marco')
("Phil"),
(Tim),
(*vancent' )
Inner Join
Combines left and right rows that match.
Table A TableB
1 1
YBNI
(—— INNER
Ll
SELECT * FROM A JOIN B ON X - Y
Lise Lisa
Marco Marco
Phil Phil
Left Outer Join
Sometimes abbreviated to "left join". Combines left and right rows that match, and includes non-matching left
rows.
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScannerTable A Table B
1 1
nus
‘oureR.
usr
SELECT = FROM A LEFT JOIN B ON X
XY
amy NULL
John NULL
Lisa Lisa
Merco Marco
Phil Phil
Right Outer Join,
Sometimes abbreviated to "right join". Combines left and right rows that match, and includes non-matching right
rows.
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
2Table A
1 1
Table B
ano
(ricer
‘SELECT + FROM A RIGHT JOIN B ON X = Y
x
Lisa
Marco
Phil
NULL
NULL
v
Lisa
Marco
Phil
Tin
Vincent
Full Outer Join
‘Sometimes abbreviated to “ful join", Union of left and right outer join.
Goalkicker.com - SQL Notes for Professionals
Scanned with CamScanner
aTable B
Nuus.
ourer.
nus
\___yaino
(uu
SELECT * FROM A FULL JOIN B ON X = Y
x y
Amy NULL
John NULL
Lisa Lisa
Marco Marco
Phil Phil
NULL Tam’
NULL Vincent
Left Semi join
Includes left rows that match right rows.
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScannerTable A Table B
(sem
ur
SELECT = FROM A WHERE X IN (SELECT Y FROM B)
x
Lisa
Marco
Phil
Right Semi oin
Includes right rows that match left rows.
Goalkicker.com - SQL Notes for Professionals
Scanned with CamScanner
6Table A Table B
semi——
RIGHT- 4
SELECT = FROM B WHERE Y IN (SELECT X FROM A)
y
Lisa
Marco
Phil
‘As you can see, there is no dedicated IN syntax for left vs. right semi join - we achieve the effect simply by switching
the table positions within SQL text.
Left Anti Semi Join
Includes left rows that do not match right rows.
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
6Table A Tabl
ANT
semi——!
err!
SELECT * FROM A WHERE X NOT IN (SELECT Y FROM B)
x
Any
John
WARNING: Be careful if you happen to be using NOT IN on a NULL-able column! More details here.
Right Anti Semi Join
Includes right rows that do net match left rows.
Goalkicker.com - SQL Notes for Professionals
Scanned with CamScanner
aTable A Table B
! 1
uNy
semi——
RIGHT
SELECT * FROM B WHERE Y NOT IN (SELECT X FROM A)
¥
Tim
Vincent
‘Asyou can see, there is no dedicated NOT IN syntax for left vs. right anti semi join - we achieve the effect simply by
switching the table positions within SQL text.
Cross Join
‘A Cartesian product of all left with allright rows.
‘SELECT * FROM A CROSS JOIN B
Lisa
Lisa
Lisa
Lisa
Lisa
Marco
Marco
Marco
Marco
Marco
Phil
Phil
Phil
Phil
Phal
Tan
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
cyJohn Tan
Lisa Tin
Marco Tim
Phil Tin
Any Vincent
John Vincent
Lisa Vincent
Marco Vincent
Phil Vincent
Cross join is equivalent to an inner join with join condition which always matches, so the following query would
have returned the same result:
SELECT * FROM A JOIN BON 1-1
Selfjoin
This simply denotes a table joining with itself. A self-join can be any of the join types discussed above, For example,
this is a an inner self oi
SELECT * FROM A A1 JOIN A A2 ON LEN(AT.X) < LEN(A2.X)
x Xx
‘Amy John
‘Any Lisa
‘Any Marco
John Marco
Lisa Marco
Phil Marco
‘Amy Phil
Section 18.4: Left Outer Join
A.Left Outer Join (also known as a Left Join or Outer Join) is a Join that ensures all rows from the left table are
represented; if no matching row from the right table exists, its corresponding fields are NULL.
The following example will select all departments and the first name of employees that work in that department,
Departments with no employees are still returned in the results, but will have NULL for the employee name:
SELECT Departments Name, Employees .FNane
FROM Departments
LEFT OUTER JOIN Employees
oN Departments Id = Employees. DepartmentId
This would return the following from the example database:
Departments.Name Employees.FName
HR James
HR John
HR Johnathon
Sales Michael
Tech NULL
‘So how does this work?
Goalkicker.com = SQL Notes for Professionals o
Scanned with CamScanner‘There are two tables in the FROM clause:
IdFName LName PhoneNumber Managerid Departmentid Salary HireDate
1 James Smith 1234567890 NULL 1 1000 01-01-2002
2 John Johnson 24681012141 1 400 23-03-2005
3 Michael Williams 13579111311 2 600 12-05-2009
4 Johnathon Smith 12121212122 1 500 24-07-2016
and
IdName
1 HR
2 Sales
3 Tech
First a Cartesian product is created from the two tables giving an intermediate table.
‘The records that meet the join criteria (Departments. Id = Employees.Departmentid) are highlighted in bold; these are
passed to the next stage of the query.
As this is a LEFT OUTER JOIN all records are returned from the LEFT side of the join (Departments), while any
records on the RIGHT side are given a NULL marker if they do not match the join criteria. In the table below this will
return Tech with NULL
IdNameidFName LName PhoneNumber Managerld Departmentld Salary HireDate
1 HR 1 James Smith 1234567890 NULL 1 1000 01-01-2002
1HR 2 John — ‘Johnson 24681012141 1 400 23-03-2005
1 HR 3 Michael Williams 13579111311 2 600 12-05-2009
1 HR 4 Johnathon Smith 12121212122 1 500 24-07-2016
2 Sales 1 James Smith 1234567890 NULL 1 1000 01-01-2002
2 Sales 2 John Johnson 24681012141 1 400 23-03-2005
2 Sales 3 Michael Williams 13579111311 2 600 12-05-2009
2 Sales 4 Johnathon Smith 12121212122 1 500 24-07-2016
3 Tech 1 James Smith 1234567890 NULL 1 1000 01-01-2002
3 Tech 2 John Johnson 24681012141 1 400 23-03-2005
3 Tech 3 Michael Williams 13579111311 2 600 12-05-2009
3 Tech 4 Johnathon Smith 12121212122 1 500 24-07-2016
Finally each expression used within the SELECT clause is evaluated to return our final table:
Departments.Name Employees.FName
HR James
HR John
Sales Richaré
Tech NULL
Section 18.5: Implicit Join
Joins can also be performed by having several tables in the from clause, separated with commas , and defining the
relationship between them in the where clause. This technique is called an Implicit join (since it doesn't actually
contain a join clause).
Goalkicker.com = SQL Notes for Professionals 70
Scanned with CamScannerAll RDBMSs support it, but the syntax is usually advised against. The reasons why it is a bad idea to use this syntax
are:
* Itis possible to get accidental cross joins which then return incorrect results, especially if you have a lot of
joins in the query.
+ Ifyou intended a cross join, then itis not clear from the syntax (write out CROSS JOIN instead), and someone
is likely to change it during maintenance.
The following example will select employee's first names and the name of the departments they work for:
SELECT e.FNome, d.Name
FROM Employee e, Departments ¢
WHERE e.DeptartwentId - d.I¢
This would return the following from the example database:
e.FNamed.Name
James HR
John HR
Richard Sales
Section 18.6: CROSS JOIN
Cross join does a Cartesian product of the two members, A Cartesian product means each row of one table is
combined with each row of the second table in the join. For example, if TABLEA has 20 rows and TABLEB has 20
rows, the result would be 26:28 = 48@ output rows.
Using example database
SELECT ¢.Name, e.FName
FROM Departments d
CROSS JOIN Employees e;
Which returns:
d.Name e.FName
HR James
HR John
HR Michael
HR Johnathon
Sales James
sales John
Sales Michael
Sales Johnathon
Tech James
Tech John
Tech Michael
Tech Johnathon
Itis recommended to write an explicit CROSS JOIN if you want to do a cartesian join, to highlight that this is what
you want.
Goalkicker.com = SQL Notes for Professionals 7
Scanned with CamScannerSection 18.7: CROSS APPLY & LATERAL JOIN
Avery interesting type of JOIN is the LATERAL JOIN (new in PostgreSQL 9.3*),
which is also known as CROSS APPLY/OUTER APPLY in SQL-Server & Oracle.
‘The basic idea is that a table-valued function (or inline subquery) gets applied for every row you join.
This makes it possible to, for example, only join the first matching entry in another table.
‘The difference between a normal and a lateral join lies in the fact that you can use a column that you previously
joined in the subquery that you "CROSS APPLY".
Syntax:
PostgreSQL 9.3+
left | right | inner JOIN LATERAL
SQL-Server:
CROSS | OUTER APPLY
INNER JOIN LATERAL is the same as CROSS APPLY
and LEFT JOIN LATERAL is the same as OUTER APPLY
Example usage (PostgreSQL 9.34):
SELECT * FROM T_Contacts
LEFT JOIN T_NAP_Contacts_Ref_OrganisationalUnit ON MAP_CTCOU_CT_UID = T_Contacts.CT_UID AND
MAP_CTCOU_SoftDeleteStatus = 1
--WHERE T_MAP_Contacts_Ref_OrganisationalUnit.MAP_CTCOU_UID IS NULL -- 989
LEFT JOIN LATERAL
fi
‘SELECT
=-MAP_CTCOU_UID
waP_cTcou_cT_uID
WAP_cTCOU_coU_UID
WAP_CTCOU_DateFrom
WAP_CTCOU_DateTo
FROM T_MAP_Contacts Ref OrganisationalUnit
WHERE MAP_CTCOU_SoftDeletestatus - 1
AND MAP_CTCOU_CT_UID - T_Contacts.cT_UID
Is
AND
(
(_-in_DateFrom <= T_MAP_Contacts Ref_OrganisationalUnit .MAP_KTKOE_DateTo)
AND
(_-in_DateTo >= TMAP_Contacts_Ref_OrganisationalUnit .MAP_KTKOE_DateF rom)
)
v
ORDER BY MAP_CTCOU_DateFrom
ut 1
Goalkicker.com = SQL Notes for Professionals 72
Scanned with CamScanner) AS Farstoe
And for SQL-Server
SELECT + FROM T_Contects
=-LEFT JOIN T_NAP_Contacts Ref OrganisationalUnit ON MAP_CTCOU_CT_UID = TContects.CT_UID AND
MAP_CTCOU_SoftDeleteStatus = 1
-WHERE T_MAP Contacts Ref_OrganisationalUnit.MAP_CTCOU_UID IS NULL -- 989
== CROSS APPLY ~
OUTER APPLY --
(
INNER JOIN
LEFT JOIN
SELECT TOP 1
=-MAP_CTCOU_UID
waP_cTcoU_cT_UID
WAP_CTCOU_COU_UID
MAP_CTCOU_DateFrom
WAP_CTCOU_DateTo
FROM T_MAP_Contacts_Ref_OrganisationalUnit
WHERE MAP_CTCOU_SoftDeleteStatus - 1
AND MAP_CTCOU_CT_UID = T_Contacts.cT_UID
is
AND
(
(@in_DateFrom <= T_MAP_Contacts_Ref_OrgenisationalUnit.MAP_KTKOE_DateTo)
AND
(@in.DateTo >= T_MAP_Contacts_Ref OrganisationalUnit.MAP_KTKOE_DateFrom)
)
7
‘ORDER BY MAP_CTCOU_DateFrom
) AS Farstoe
Section 18.8: FULL JOIN
One type of JOIN that is less known, is the FULL JOIN.
(Note: FULLJOIN is not supported by MySQL as per 2016)
AFULL OUTER JOIN returns all rows from the left table, and all rows from the right table.
If there are rows in the left table that do not have matches in the right table, or if there are rows in right table that
Go not have matches in the left table, then those rows willbe listed, too.
Example 1
SELECT * FROM Table?
FULL JOIN Table2
ON 1 =2
Example 2:
SELECT
COALESCE(T_Budget.Year, tYear.vear) AS RPT_BudgetInYear
COALESCE(T-Budget. Value, @.€) AS RPT Value
FROM T_Budget
FULL JOIN tfu_RPT_A11_CreateYearInterval(obudget_yea!
from, @budget_year_to) AS tYear
Goalkicker.com = SQL Notes for Professionals B
Scanned with CamScannerON tYear.Year = T_Budget.¥
Note that if you're using soft-deletes, you'll have to check the soft-delete status again in the WHERE-clause (because
FULL JOIN behaves kind-of like a UNION);
It’s easy to overlook this little fact, since you put AP_SoftDeleteStatus = 1 in the join clause.
A\so, if you are doing a FULL JOIN, youll usually have to allow NULL in the WHERE-clause; forgetting to allow NULL
on a value will have the same effects as an INNER join, which is something you dont want if you're doing a FULL
JOIN.
Example
‘SELECT
T_AccountPlan. AP_UID
T-AccountPlan..AP_Code
T_AccountPlan..AP_Lang_£N
T_BudgetPositions. BUP_Budget
T_BudgetPositions. BUP_UID
T_BudgetPositions. BUP_Jahr
FROM T_BudgetPositions
FULL JOIN T_AccountPlan
(ON T_AccountPlan. AP_UID = T_BudgetPositions.BUP_AP_UID
AND T_AccountPlan.AP_SoftDeleteStatus = 1
WHERE (1=1)
AND (T_BudgetPositions.BUP_SoftDeleteStatus = 1 OR T_BudgetPositions.BUP_SoftDeleteStatus IS NULL)
AND (T_AccountPlan.AP_SoftDeleteStatus = 1 OR T_AccountPlan.AP_SoftDeleteStatus IS NULL)
Section 18.9: Recursive JOINS
Recursive joins are often used to obtain parent-child data. In SQL, they are implemented with recursive common
table expressions, for example:
WITH RECURSIVE MyDescendants AS (
SELECT Name
FROM People
WHERE Name = ‘John Doe’
UNION ALL
SELECT People.Nane
FROM People
JOIN MyDescendants ON People. Name = MyDescendants Parent
SELECT * FROM Hyoescendants
Section 18.10: Basic explicit inner join
A basic join (also called “inner join") queries data from two tables, with their relationship defined in a join clause.
The following example will select employees’ first names (FName) from the Employees table and the name of the
department they work for (Name) from the Departments table:
SELECT Employees.FName, Departments.Nane
FROM Employees
JOIN Departments
Goalkicker.com = SQL Notes for Professionals 74
Scanned with CamScannerON Employees. DepartmentId = Departments.Id
This would return the following from the example database:
Employees.FName Departments.Name
James HR
John HR
Richard Sales
Section 18.11: Joining on a Subquery
Joining a subquery is often used when you want to get aggregate data from a child/details table and display that
along with records from the parent/header table. For example, you might want to get a count of child records, an
average of some numeric column in child records, or the top or bottom row based on a date or numeric field. This
example uses aliases, which arguable makes queries easier to read when you have multiple tables involved. Here's
what a fairly typical subquery join looks like, In this case we are retrieving all rows from the parent table Purchase
Orders and retrieving only the first row for each parent record of the child table PurchaseOrderLineltems.
SELECT po.Id, po.PODate, po.VendorName, po.Status, item. ItenNo,
Atem.Deseription, item Cost, item. Price
FROM PurchaseOrders po
LEFT JOIN
(
SELECT 1.PurchaseOrderId, 1.ItemNo, 1.Description, 1.Cost, 1.Price, Min(1.id) as Id
FROM PurchaseOrderLineLtems 1
GROUP BY 1.PurchaseOrderId, 1.ItenNo, 1.Description, 1.Cost, 1.Price
) AS item ON item.PurchaseOrderId = po.Id
Goalkicker.com - SQL Notes for Professionals 5
Scanned with CamScannerChapter 19: UPDATE
Section 19.1: UPDATE with data from another table
The examples below fil in a PhoneNumber for any Employee who is also a Custoner and currently does not have a
phone number set in the Employees Table.
(These examples use the Employees and Customers tables from the Example Databases.)
Standard SQL
Update using a correlated subquery:
UPDATE
Employees
‘SET PhoneNumber =
(SELECT
.PhoneNumber
FROM
Customers ¢
WHERE
©.FNane = Employees. FNane
AND c.LName = Employees. LName)
WHERE Enployees.PhoneNumber IS NULL
$QL:2003
Update using MeRcE:
MERGE INTO
Employees €
USING
Customers ¢
on
e.FName = ¢.Fnane
AND e.LName = c.LName
AND e.PhoneNumber IS NULL
WHEN MATCHED THEN
upDATE
SET PhoneNumber = c.PhoneNunber
SQL Server
Update using INNER JOIN:
UPDATE
Employees
se
PhoneNunber - ¢.PhoneNunber
FROM
Employees ¢
INNER JOIN Customers ¢
ON e.FName = c.FName
AND e.LName = ¢.LNane
WHERE
PhoneNumber I$ NULL
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
76Section 19.2: Modifying existing values
This example uses the Cars Table from the Example Databases.
UpoaTE cars
SET TotalCost - TotalCost + 100
WHERE Td = 3 or Id = 4
Update operations can include current values in the updated row. In this simple example the TotelCost is
incremented by 100 for two rows:
‘+ The TotalCost of Car #3 is increased from 100 to 200,
‘* The TotalCost of Car #4 is increased from 1254 to 1354
‘Acolumn's new value may be derived from its previous value or from any other column's value in the same table or
ajoined table.
Section 19.3: Updating Specified Rows
This example uses the Cars Table from the Example Databases.
pate
cars
ser
status = ‘READY’
WHERE
Td = 4
This statement will set the status of the row of ‘Cars’ with id 4 to "READY".
INHERE clause contains a logical expression which is evaluated for each row. Ifa row fulfils the criteria, its value is
updated, Otherwise, a row remains unchanged.
Section 19.4: Updating All Rows
This example uses the Cars Table from the Example Databases.
UPDATE Cars
SET Status = ‘READY
This statement will set the ‘status’ column of all rows of the ‘Cars’ table to "READY" because it does not have a WHERE
clause to filter the set of rows.
Section 19.5: Capturing Updated records
‘Sometimes one wants to capture the records that have just been updated.
CREATE TABLE #TempUpdated( 1D INT)
Update TebleNane SET Colt - 42
OUTPUT inserted.ID INTO #TempUpdated
WHERE Id > 50
Goalkicker.com = SQL Notes for Professionals 7
Scanned with CamScannerChapter 20: CREATE Database
Section 20.1: CREATE Database
A database is created with the following SQL command:
CREATE DATABASE myDatabase
This would create an empty database named myDatabase where you can create tables.
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScannerChapter 21: CREATE TABLE
Parameter Details
tableName The name of the table
Contains an ‘enumeration’ of all the columns that the table have. See Create a New Table for more
Getails.
‘The CREATE TABLE statement is used create a new table in the database. A table definition consists of a list of
columns, their types, and any integrity constraints.
columns
Section 21.1: Create Table From Select
You may want to create a duplicate of a table:
CREATE TABLE ClonedEmployees AS SELECT * FROM Employees ;
‘You can use any of the other features of a SELECT statement to modify the data before passing it to the new table,
‘The columns of the new table are automatically created according to the selected rows.
CREATE TABLE ModifiedEmployees AS
SELECT Td, CONCAT(FName," ",LName) AS FullName FROM Employees
WHERE Id > 10
Section 21.2: Create a New Table
Abasic Employees table, containing an ID, and the employee's first and last name along with their phone number
can be created using
CREATE TABLE Enployees:
Id int identity(1,1) primary key not null.
FName varchar(2@) not null,
LName varchar(2@) not null,
PhoneNumber varchar(1@) not null
This example is specific to Transact-SQL
CREATE TABLE creates anew table in the database, followed by the table name, Employees
This is then followed by the list of column names and their properties, such as the ID
Id int identity(1,1) not null
Value Meaning
ad the column's name.
int is the cata type.
states that column will have auto generated values starting at 1 and incrementing by 1 for each
Adentity(1,1
new row.
primary key states thatall values in this column will have unique values
not null states that this column cannot have null values
Section 21.3: CREATE TABLE With FOREIGN KEY
Below you could fing the table Employees with a reference to the table Cities.
Goalkicker.com = SQL Notes for Professionals 79
Scanned with CamScannerCREATE TABLE Cities(
CityID INT IDENTITY(1,1) NOT NULL,
Name VARCHAR(2@) NOT NULL.
ip VARCHAR(1@) NOT NULL
CREATE TABLE Employees(
EmployeeID INT IDENTITY (1,1) NOT NULL,
FirstName VARCHAR(28) NOT NULL
LastName VARCHAR(2@) NOT NULL,
PhoneNumber VARCHAR(1@) NOT NULL
CityID INT FOREIGN KEY REFERENCES Cities(CityID)
Here could you find a database diagram.
Employees
EmployeeID
FirstName
Field
PhoneNumber
CityID
‘The column City10 of table Employees will reference to the column CityID of table Cities. Below you could find
the syntax to make this.
CityLD INT FOREIGN KEY REFERENCES Cities(CityID)
Value Meaning
cityIo Name of the column
int type of the column
FOREIGN KEY Makes the foreign key (optional)
REFERENCES Makes the reference
Cities (City10) to the table Cities column cityID
Important: You couldn't make a reference to a table that not exists in the database. Be source to make first the
table Cities and second the table Employees. If you do it vise versa, it will throw an error.
Section 21.4: Duplicate a table
To duplicate a table, simply do the following:
CREATE TABLE newtable LIKE oldtable
INSERT newtable SELECT * FROM oldtable
Section 21.5: Create a Temporary or In-Memory Table
PostgreSQL and SQLite
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
80To create a temporary table local to the session:
CREATE TEMP TABLE MyTable(....)
SQL Server
To create a temporary table local to the session:
CREATE TABLE #TempPhysicel(...)
To create a temporary table visible to everyone:
CREATE TABLE #8TempPhysicalVi sibleToEveryone(
To create an in-memory table:
DECLARE @TempMemory TABLE(...);
)
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
aChapter 22: CREATE FUNCTION
‘Argument Description
function.name the name of function
list_of_paramenters parameters that function accepts
return_datatype _ type that function returs. Some SQL data type
function body the code of function
scalar_expression scalar value returned by function
Section 22.1: Create a new Function
CREATE FUNCTION FirstWord (@input varchar (1680) )
RETURNS varchar (1000)
as.
‘BEGIN
DECLARE Goutput varchar (1088)
‘SET @output = SUBSTRING(@input, @, CASE CHARINDEX(' ', @input)
WHEN @ THEN LEN(@input) + 1
ELSE CHARINDEX(' ", @input
END)
RETURN @output
END
This example creates a function named FirstWord, that accepts a varchar parameter and returns another varchar
value.
Goalkicker.com = SQL Notes for Professionals 82
Scanned with CamScannerChapter 23: TRY/CATCH
Section 23.1: Transaction In a TRY/CATCH
This will rollback both inserts due to an invalid datetime:
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO dbo Sale(Price
VALUES (5.2, GETDATE(), 1)
INSERT INTO dbo.Sale(Price,
VALUES (5.2, ‘not a date
COMMIT TRANSACTION
END TRY
BEGIN CATCH
THROW
ROLLBACK TRANSACTION
END CATCH
This will commit both inserts:
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO dbo Sale(Price
VALUES (5.2, GETDATE(), 1)
INSERT INTO dbo. Sale(Price
VALUES (5.2, GETDATE(), 1)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
THROW
ROLLBACK TRANSACTION
END CATCH
SaleDate, Quantity)
SaleDate, Quantity)
1)
SaleDate, Quantity)
SaleDate, Quantity)
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
aChapter 24: UNION / UNION ALL
UNION keyword in SQL is used to combine to SELECT statement results with out any duplicate. In order to use
UNION and combine results both SELECT statement should have same number of column with same data type in
same order, but the length of column can be different.
Section 24.1: Basic UNION ALL query
CREATE TABLE HR_EMPLOYEES
t
PersonID int
LastName VARCHAR(30)
FirstName VARCHAR(38),
Position VARCHAR(3@)
CREATE TABLE FINANCE EMPLOYEES
PersonID INT.
LastName VARCHAR(30)
FirstName VARCHAR(30),
Position VARCHAR(38)
Let's say we want to extract the names of all the managers from our departments.
Using a UNION we can get all the employees from both HR and Finance departments, which hold the position of a
manager
‘SELECT
FirstName, LastName
FROM
HR_EMPLOYEES
WHERE
Position = 'm:
UNTON ALL
SELECT
FirstName, LastName
FROM
FINANCE EMPLOYEES
WHERE
Position - ‘manager’
age
‘The UNION statement removes duplicate rows from the query results, Since itis possible to have people having the
same Name and position in both departments we are using UNTON ALL, in order not to remove duplicates,
If you want to use an alias for each output column, you can just put them in the first select statement, as follows:
SELECT
FirstName as ‘First Name’, LastName as ‘Last Name’
FROM
HR_EMPLOYEES
WHERE
Position = ‘manager’
UNION ALL
SELECT
FirstName, LastName
FROM
Goalkicker.com = SQL Notes for Professionals 84
Scanned with CamScannerFINANCE EMPLOYEES
WHERE
Position = ‘manager’
Section 24.2: Simple explanation and Example
in simple terms:
‘+ UNTON joins 2 result sets while removing duplicates from the result set
‘* UNION ALL joins 2 result sets without attempting to remove duplicates
(One mistake many people make Is to use a UNZON when they do not need to have the duplicates removed.
The additional performance cost against large results sets can be very significant.
‘When you might need UNION
Suppose you need to filter a table against 2 cifferent attributes, and you have created separate non-clustered
indexes for each column. A UNTON enables you to leverage both indexes while still preventing duplicates.
SELECT C1, C2, C3 FROM Tablet WHERE C1 = @Parant
‘UNION
SELECT C1, C2, C3 FROM Tablet WHERE C2 = @Paranz
This simplifies your performance tuning since only simple indexes are needed to perform these queries optimally.
You may even be able to get by with quite a bit fewer non-clustered indexes improving overall write performance
against the source table as well,
When you might need UNION ALL
Suppose you stil need to filter a table against 2 attributes, but you do not need to filter duplicate records (either
because it doesn't matter or your data wouldn't produce any duplicates during the union due to your data model
design).
SELECT C1 FROM Tablet
UNION ALL.
SELECT C1 FROM Table2
This is especially useful when creating Views that join data that is designed to be physically partitioned across
multiple tables (maybe for performance reasons, but still wants to roll-up records). Since the data is already split,
having the database engine remove duplicates adds no value and just adds additional processing time to the
queries.
Goalkicker.com = SQL Notes for Professionals cS
Scanned with CamScannerChapter 25: ALTER TABLE
ALTER command in SQL is used to modify column/constraint in a table
Section 25.1: Add Column(s)
ALTER TABLE Employees
ADD StartingDate date NOT NULL DEFAULT GetDate()
DateOfBirth date NULL
‘The above statement would add columns named StartingDate which cannot be NULL with default value as current
Gate and DateofBirth which can be NULL in Employees table.
Section 25.2: Drop Column
ALTER TABLE Employes
DROP COLUMN salary
This will not only delete information from that column, but will drop the column salary from table employeesithe
column will no more exist).
Section 25.3: Add Primary Key
ALTER TABLE EMPLOYEES ADD pk EmployeeID PRIMARY KEY (ID)
This will add a Primary key to the table Employees on the field ID. Including more than one column name in the
parentheses along with ID will create a Composite Primary Key. When adding more than one column, the column
names must be separated by commas.
ALTER TABLE EMPLOYEES ADD pk_EmployeeTD PRIMARY KEY (1D, FName)
Section 25.4: Alter Column
ALTER TABLE Employees
ALTER COLUMN StartingDate DATETIME NOT NULL DEFAULT (GETDATE())
This query will alter the column datatype of StartingDate and change it from simple date to datetime and set
default to current date.
Section 25.5: Drop Constraint
ALTER TABLE Employees
DROP CONSTRAINT DefaultSalary
This Drops a constraint called DefaultSalary from the employees table definition,
Note: Ensure that constraints of the column are dropped before dropping a column.
Goalkicker.com = SQL Notes for Professionals 6
Scanned with CamScannerChapter 26: INSERT
Section 26.1: INSERT data from another table using SELECT
INSERT INTO Customers (FName, LName, PhoneNunber)
SELECT FName, LName, PhoneNumber FROM Employees
This example will insert all Employees into the Customers table. Since the two tables have different fields and you
don't want to move all the fields over, you need to set which fields to insert into and which fields to select. The
correlating field names don't need to be called the same thing, but then need to be the same data type. This,
example is assuming that the I¢ field has an Identity Specification set and will auto increment.
Ifyou have two tables that have exactly the same field names and just want to move all the records over you can
use:
INSERT INTO Tablet
SELECT * FROM Table2
Section 26.2: Insert New Row
INSERT INTO Customers
VALUES (‘Zack', ‘Smith’, ‘[email protected]’, '7649989942', ‘EMAIL")
This statement will insert a new row into the Customers table. Note that a value was not specified for the Id column,
as itwill be added automatically. However, all other column values must be specified,
Section 26.3: Insert Only Specified Columns
INSERT INTO Customers (FName, LName, Email, PreferredContact)
VALUES (‘Zack', ‘Smith’, ‘[email protected]’, ‘EMAIL');
This statement will insert a new row into the Customers table. Data will only be inserted into the columns specified -
ote that no value was provided for the PhoneNumber column. Note, however, that all columns marked as not null
must be included.
Section 26.4: Insert multiple rows at once
Multiple rows can be inserted with a single insert command:
INSERT INTO tbl_name (field1, field2, field3)
VALUES (12.3), (4,5,6), (7.8,9)
For inserting large quantities of data (bulk insert) at the same time, DBMS-specifc features and recommendations
exist
MySQL - LOAD DATA INFILE
MSSQL - BULK INSERT
Goalkicker.com = SQL Notes for Professionals a7
Scanned with CamScannerChapter 27: MERGE
MERGE (often also called UPSERT for "update or insert") allows to insert new rows or, ifa row already exists, to
update the existing row. The point is to perform the whole set of operations atomically (to guarantee that the data
remain consistent), and to prevent communication overhead for multiple SQL statements in a client/server system.
Section 27.1: MERGE to make Target match Source
MERGE INTO targetTable t
USING sourceTable s
(ON t.PKID = s.PKID
WHEN MATCHED AND NOT EXISTS (
SELECT s.ColumnA, s.ColunB, s.Column¢
INTERSECT
SELECT t.Columna, t.ColumnB, s.Colunnc
THEN UPDATE SET
t.Columna = s.Colunna
t.ColumnB = s.Colunns
t.Columnc = s.colunnc
WHEN NOT MATCHED BY TARGET
THEN INSERT (PKID, ColumnA, ColunnB, ColumnC)
VALUES (s.PKID, s.ColumnA, s.ColumnB, s.Column¢
WHEN NOT MATCHED BY SOURCE
THEN DELETE
Note: The AND NOT EXISTS portion prevents updating records that haven't changed. Using the INTERSECT construct
allows nullable columns to be compared without special handling,
Section 27.2: MySQL: counting users by name
‘Suppose we want to know how many users have the same name. Let us create table users as follows:
create table users(
id int primary key auto_increment,
name varchar (8)
count int,
unique key name (name)
Now, we just discovered a new user named Joe and would like to take him into account. To achieve that, we need to
determine whether there is an existing row with his name, and if so, update it to increment count; on the other
hand, if there is no existing row, we should create it
MySQL uses the following syntax : insert .. on duplicate key update ... In this case:
insert into users(name, count)
values (‘Joe’, 1)
on duplicate key update count=count+1
Section 27.3: PostgreSQL: counting users by name
Suppose we want to know how many users have the same name. Let us create table users as follows:
Goalkicker.com = SQL Notes for Professionals 88
Scanned with CamScannercreate table users(
id serial,
name varchar(8) unique,
count int
Now, we just discovered a new user named Joe and would like to take him into account. To achieve that, we need to
determine whether there is an existing row with his name, and if so, update it to increment count; on the other
hang, if there is no existing row, we should create it.
PostgreSQL uses the following syntax : insert ... on conflict .. do update... In this ca
insert into users(name, count)
values(*Joe’, 1)
fon conflict (name) do update set count = users.count + 1
Goalkicker.com = SQL Notes for Professionals
Scanned with CamScanner
aChapter 28: cross apply, outer apply
Section 28.1: CROSS APPLY and OUTER APPLY basics
Apply will be used when when table valued function in the right expression.
create a Department table to hold information about departments. Then create an Employee table which hold
information about the employees. Please note, each employee belongs to a department, hence the Employee table
has referential integrity with the Department table.
First query selects data from Department table and uses CROSS APPLY to evaluate the Employee table for each
record of the Department table. Second query simply joins the Department table with the Employee table and all
the matching records are produced.
SELECT *
FROM Department D
CROSS APPLY
‘SELECT *
FROM Employee E
WHERE E.DepartmentID = D.Department1D
yA
co
SELECT *
FROM Department D
INNER JOIN Employee &
ON D.DepartmentID = E.DepartmentID
If you look at the results they produces, itis the exact same result-set; How does it differ from a JOIN and how does
it help in writing more efficient queries.
‘The first query in Script #2 selects data from Department table and uses OUTER APPLY to evaluate the Employee
table for each record of the Department table. For those rows for which there is not a match in Employee table,
those rows contains NULL values as you can see in case of row 5 and 6. The second query simply uses a LEFT
CUTER JOIN between the Department table and the Employee table. As expected the query returns all rows from
Department table; even for those rows for which there is no match in the Employee table.
SELECT *
FROM Department D
OUTER APPLY
SELECT «
FROM Employee E
WHERE E DepartmentID = 0 DepartmentID
yA
60
SELECT +
FROM Department D
LEFT OUTER JOIN Employee E
ON D.DepartmentID = E.DepartmentID
co
Even though the above two queries return the same information, the execution plan will be bit different, But cost
wise there will be not much difference.
Now comes the time to see where the APPLY operator is really required. In Script #3, | am creating a table-valued
function which accepts DepartmentlD as its parameter and returns all the employees who belong to this,
department. The next query selects data from Department table and uses CROSS APPLY to join with the function
Goalkicker.com = SQL Notes for Professionals 90
Scanned with CamScanner