Best Practices Transact-SQL
Jan 08, 2018
Best PracticesTransact-SQL
Transact-SQL Syntax Elements
Batch Directives Comments Identifiers Types of Data Variables
System Functions Operators Expressions Control-of-Flow
Language Elements Reserved Keywords
Batch Directives
GO Delineates batches of Transact-SQL statements to tools
and utilities Is not an actual Transact-SQL statement
EXEC Executes a user-defined function, system procedure,
user-defined stored procedure, or an extended stored procedure
Controls the execution of a character string within a Transact-SQL batch
Comments
In-line Comments
Block Comments
SELECT productname, (unitsinstock - unitsonorder) -- Calculates inventory, supplierIDFROM productsGO
/* This code retrieves all rows of the products table and displays the unit price, the unit price increased by 10 percent, and the name of the product. */USE northwindSELECT unitprice, (unitprice * 1.1), productname FROM productsGO
Example 3
Example 1
Identifiers
Standard Identifiers First character must be alphabetic Other characters can include letters, numerals, or
symbols
Identifiers starting with symbols have special uses Delimited Identifiers
Use when names contain embedded spaces Use when reserved words are portions of names Enclose in brackets ([ ]) or quotation marks (" ")
Naming Guidelines for Identifiers
Keep Names Short Use Meaningful Names Where Possible Use Clear and Simple Naming Conventions Use an Identifier That Distinguishes Types of Object
Views Stored procedures
Keep Object Names and User Names Unique Sales table and sales role
Types of Data
Numbers Dates Characters Binary Unique Identifiers (GUID)
SQL Variants Image and Text Table Cursor User-defined
Variables
User-defined with DECLARE @ Statement Assigned Values with SET or SELECT @ Statement Variables Have Local Scope
USE northwindDECLARE @EmpID varchar(11) ,@vlName char(20)SET @vlname = 'Dodsworth'SELECT @EmpID = employeeid FROM employees WHERE LastName = @vlnameSELECT @EmpID AS EmployeeID GO
System Functions
Aggregate Functions
Scalar Functions
Rowset FunctionsSELECT * FROM OPENQUERY (OracleSvr, 'SELECT name, id FROM owner.titles')
USE northwindSELECT AVG (unitprice) AS AvgPrice FROM productsGO
USE northwindSELECT DB_NAME() AS 'database‘GO
System Function Examples
SELECT 'ANSI:', CONVERT(varchar(30), GETDATE(), 102) AS StyleUNIONSELECT 'Japanese:', CONVERT(varchar(30), GETDATE(), 111)UNIONSELECT 'European:', CONVERT(varchar(30), GETDATE(), 113)GO
Result
StyleStyleANSI:Japanese:European:
1998.03.191998/03/1919 Mar 1998 16:34:40:616
Example 1
Operators
Types of Operators Arithmetic
Comparison
String concatenation
Logical
Operator Precedence Levels
Expressions
Combination of Symbols and Operators Evaluation to Single Scalar Value Result Data Type Dependent on the Elements
Within the Expression
USE northwindSELECT OrderID, ProductID ,(UnitPrice * Quantity) as ExtendedAmount FROM [Order Details] WHERE (UnitPrice * Quantity) > 10000GO
Control-of-Flow Language Elements
Statement Level BEGIN … END block
IF … ELSE block
WHILE constructs
Row Level CASE function
DECLARE @n tinyintSET @n = 5IF (@n BETWEEN 4 and 6) BEGIN WHILE (@n > 0) BEGIN SELECT @n AS 'Number' ,CASE WHEN (@n % 2) = 1 THEN 'EVEN' ELSE 'ODD' END AS 'Type' SET @n = @n - 1 END ENDELSE PRINT 'NO ANALYSIS‘GO
Example 2
Reserved Keywords
Identifier Names That Have Special Meaning Transact-SQL keywords
ANSI SQL-92 keywords
ODBC reserved keywords
Do Not Use Reserved Keywords for Identifier Names
Retrieving Data by Using the SELECT Statement
Using the SELECT Statement Specifying Columns Using the WHERE Clause to Specify Rows
SELECT [ALL | DISTINCT] <select_list> FROM {<table_source>} [,…n] WHERE <search_condition>
Partial Syntax
Using the SELECT Statement
Select List Specifies the Columns WHERE Clause Specifies the Condition Restricting the
Query FROM Clause Specifies the Table
Specifying Columns
employeeidemployeeid lastnamelastname firstnamefirstname titletitle1 Davolio Nancy Sales Representative2 Fuller Andrew Vice President, Sales3 Leverling Janet Sales Representative4 Peacock Margaret Sales Representative5 Buchanan Steven Sales Manager6 Suyama Michael Sales Representative7 King Robert Sales Representative8 Callahan Laura Inside Sales Coordinator9 Dodsworth Anne Sales Representative
USE northwindSELECT employeeid, lastname, firstname, titleFROM employeesGO
Using the WHERE Clause to Specify Rows
employeeidemployeeid lastnamelastname firstnamefirstname titletitle5 Buchanan Steven Sales Manager
USE northwindSELECT employeeid, lastname, firstname, titleFROM employeesWHERE employeeid = 5GO
Filtering Data
Using Comparison Operators Using String Comparisons Using Logical Operators Retrieving a Range of Values Using a List of Values as Search Criteria Retrieving Unknown Values
Using Comparison Operators
USE northwindSELECT lastname, cityFROM employeesWHERE country = 'USA'GO
lastnamelastname citycityDavolio SeattleFuller TacomaLeverling KirklandPeacock RedmondCallahan Seattle
Example 1
Using String Comparisons
USE northwindSELECT companynameFROM customersWHERE companyname LIKE '%Restaurant%'GO
companynamecompanynameGROSELLA-RestauranteLonesome Pine RestaurantTortuga Restaurante
Using Logical Operators
USE northwindSELECT productid, productname, supplierid, unitprice FROM products WHERE (productname LIKE 'T%' OR productid = 46) AND (unitprice > 16.00) GO
productidproductid productnameproductname supplieridsupplierid unitpriceunitprice14 Tofu 6 23.2529 Thüringer Rostbratwurst 12 123.7962 Tarte au sucre 29 49.3
Example 1
Retrieving a Range of Values
USE northwindSELECT productname, unitpriceFROM productsWHERE unitprice BETWEEN 10 AND 20GO
productnameproductname unitpriceunitpriceChai 18Chang 19Aniseed Syrup 10Genen Shouyu 15.5Pavlova 17.45Sir Rodney’s Scones 10… …
Example 1
USE northwindSELECT companyname, countryFROM suppliersWHERE country IN ('Japan', 'Italy')GO
Using a List of Values as Search Criteria
companynamecompanyname countrycountryTokyo Traders JapanMayumi’s JapanFormaggi Fortini s.r.l. ItalyPasta Buttini s.r.l. Italy
Example 1
Retrieving Unknown Values
USE northwindSELECT companyname, faxFROM suppliersWHERE fax IS NULLGO
companynamecompanyname faxfaxExotic Liquids NULLNew Orleans Cajun Delights NULLTokyo Traders NULLCooperativa de Quesos ‘Las Cabras’ NULL… …
Formatting Result Sets
Sorting Data Eliminating Duplicate Rows Changing Column Names Using Literals
Sorting Data
USE northwindSELECT productid, productname, categoryid, unitprice FROM products ORDER BY categoryid, unitprice DESCGO
productidproductid productnameproductname categoryidcategoryid unitpriceunitprice38 Cote de Blaye 1 263.500043 Ipoh Coffee 1 46.00002 Chang 1 19.0000… … … …63 Vegie-spread 2 43.90008 Northwoods Cranberry Sauce 2 40.000061 Sirop d'érable 2 28.5000… … … …
Example 1
Eliminating Duplicate Rows
USE northwindSELECT DISTINCT country FROM suppliers ORDER BY countryGO
countrycountryAustraliaBrazilCanadaDenmarkFinlandFranceGermanyItalyJapanNetherlandsNorwaySingaporeSpainSwedenUKUSA
Example 1
Changing Column Names
USE northwindSELECT firstname AS First, lastname AS Last
,employeeid AS 'Employee ID:' FROM employeesGO
FirstFirst LastLast Employee ID:Employee ID:Nancy Davolio 1Andrew Fuller 2Janet Leverling 3Margaret Peacock 4Steven Buchanan 5Michael Suyama 6Robert King 7Laura Callahan 8Anne Dodsworth 9
Using Literals
USE northwindSELECT firstname, lastname
,'Identification number:', employeeidFROM employeesGO
FirstFirst LastLast Employee ID:Employee ID:Nancy Davolio Identification Number: 1Andrew FullerJanet LeverlingMargaret PeacockSteven BuchananMichael SuyamaRobert KingLaura CallahanAnne Dodsworth
Identification Number: 2Identification Number: 3Identification Number: 4Identification Number: 5Identification Number: 6Identification Number: 7Identification Number: 8Identification Number: 9
How Queries Are Processed
Uncached Queries (Ad Hoc)
Cached Queries
ExecuteCompileOptimizeResolveParse
First Execution
ExecuteCompileOptimizeResolveParse
Subsequent Execution ExecuteProcedureCache
Performance Considerations
Not Search Conditions May Slow Data Retrieval LIKE Search Conditions Slow Data Retrieval Exact Matches or Ranges May Speed Data Retrieval ORDER BY Clause May Slow Data Retrieval
Listing the TOP n Values
Lists Only the First n Rows of a Result Set Specifies the Range of Values in the ORDER BY Clause Returns Ties if WITH TIES Is Used
USE northwindSELECT TOP 5 orderid, productid, quantity FROM [order details] ORDER BY quantity DESCGO
USE northwindSELECT TOP 5 WITH TIES orderid, productid, quantity FROM [order details] ORDER BY quantity DESCGO
Example 1
Example 2
Using Aggregate Functions
Aggregate functionAggregate function DescriptionDescriptionAVG Average of values in a numeric expression
COUNT Number of values in an expression
COUNT (*) Number of selected rows
MAX Highest value in the expression
MIN Lowest value in the expression
SUM Total values in a numeric expression
STDEV Statistical deviation of all values
STDEVP Statistical deviation for the population
VAR Statistical variance of all values
VARP Statistical variance of all values for the population
Using Aggregate Functions with Null Values
Most Aggregate Functions Ignore Null Values COUNT(*) Function Counts Rows with Null Values
USE northwindSELECT COUNT (*) FROM employeesGO
USE northwindSELECT COUNT(reportsto) FROM employeesGO
Example 1
Example 2
GROUP BY Fundamentals
Using the GROUP BY Clause Using the GROUP BY Clause with the HAVING Clause
Using the GROUP BY ClauseUSE northwindSELECT productid, orderid ,quantity FROM orderhistGO
USE northwindSELECT productid ,SUM(quantity) AS total_quantity FROM orderhist GROUP BY productidGO
productidproductid total_quantitytotal_quantity1 15
2 35
3 45
productidproductid orderidorderid quantityquantity1 1 5
1 1 10
2 1 10
2 2 25
3 1 15
3 2 30
productidproductid total_quantitytotal_quantity2 35
Only rows thatsatisfy the WHERE clause are grouped
USE northwindSELECT productid ,SUM(quantity) AS total_quantity FROM orderhist WHERE productid = 2 GROUP BY productidGO
Using the GROUP BY Clause with the HAVING Clause
USE northwindSELECT productid, orderid ,quantity FROM orderhistGO
USE northwindSELECT productid, SUM(quantity) AS total_quantity FROM orderhist GROUP BY productid HAVING SUM(quantity)>=30GO
productidproductid total_quantitytotal_quantity2 35
3 45
productidproductid orderidorderid quantityquantity1 1 5
1 1 10
2 1 10
2 2 25
3 1 15
3 2 30
Generating Aggregate Values Within Result Sets
Using the GROUP BY Clause with the ROLLUP Operator Using the GROUP BY Clause with the CUBE Operator Using the GROUPING Function
Description
Using the GROUP BY Clause with the ROLLUP OperatorUSE northwindSELECT productid, orderid, SUM(quantity) AS total_quantity FROM orderhist GROUP BY productid, orderid WITH ROLLUP ORDER BY productid, orderidGOproductidproductid orderidorderid total_quantitytotal_quantity
NULL NULL 951 NULL 151 1 51 2 102 NULL 352 1 102 2 253 NULL 453 1 153 2 30
Grand total
Summarizes only rows for productid 1Detail value for productid 1, orderid 1Detail value for productid 1, orderid 2Summarizes only rows for productid 2Detail value for productid 2, orderid 1Summarizes only rows for productid 3Detail value for productid 3, orderid 1Detail value for productid 3, orderid 2
Using the GROUP BY Clause with the CUBE Operator
The CUBE operatorproduces two more summaryvalues than theROLLUP operator
USE northwindSELECT productid, orderid, SUM(quantity) AS total_quantity FROM orderhist GROUP BY productid, orderid WITH CUBE ORDER BY productid, orderidGO
DescriptionGrand total
Summarizes all rows for orderid 1Summarizes all rows for orderid 2Summarizes only rows for productid 1Detail value for productid 1, orderid 1Detail value for productid 1, orderid 2Summarizes only rows for productid 2Detail value for productid 2, orderid 1Detail value for productid 2, orderid 2Summarizes only rows for productid 3Detail value for productid 3, orderid 1Detail value for productid 3, orderid 2
productidproductid orderidorderid total_quantitytotal_quantityNULL NULL 95NULL 1 30NULL 2 65
1 NULL 151 1 51 2 102 NULL 352 1 102 2 253 NULL 453 1 153 2 30
1 represents summary values in the preceding column
0 represents detail values in the preceding column
953065155
10351025451530
Using the GROUPING FunctionSELECT productid, GROUPING (productid) ,orderid, GROUPING (orderid) ,SUM(quantity) AS total_quantity FROM orderhist GROUP BY productid, orderid WITH CUBE ORDER BY productid, orderidGO
productidproductidNULLNULLNULL
111222333
111000000000
orderidorderidNULL
12
NULL12
NULL12
NULL12
100100100100
total_quantitytotal_quantity
Using the COMPUTE and COMPUTE BY ClausesCOMPUTE BYCOMPUTE
USE northwindSELECT productid, orderid, quantity FROM orderhist ORDER BY productid, orderid COMPUTE SUM(quantity) BY productid COMPUTE SUM(quantity)GO
USE northwindSELECT productid, orderid ,quantity FROM orderhistORDER BY productid, orderidCOMPUTE SUM(quantity)GO
productidproductid orderidorderid quantityquantity1 1 51 2 102 1 102 2 253 1 153 2 30
sum 95
productidproductid orderidorderid quantityquantity1 1 51 2 10
sum 152 1 102 2 25
sum 353 1 153 2 30
sum 45sum 95
Using Aliases for Table Names
Example 1 (without an alias name)
Example 2 (with an alias name)USE joindbSELECT buyer_name, s.buyer_id, qty FROM buyers AS b INNER JOIN sales AS s ON b.buyer_id = s.buyer_idGO
USE joindb SELECT buyer_name, sales.buyer_id, qty FROM buyers INNER JOIN sales ON buyers.buyer_id = sales.buyer_idGO