Too busy to learn the new capabilities of SQL Server? This session will cover several of the new features of the T-SQL language, specifically Common Table Expressions (CTE's) and Windowing Functions. This will be an code-heavy session with examples hat you can readily leverage in your solutions.
The focus will be on techniques to shape and manipulate your data for easier consumption by your application, and to leverage your SQL Server to avoid writing code in your application.
A basic to intermediate understanding of T-SQL is required.
Simplifying SQL with CTE's and windowing functions
1. Edit
Simplifying and improving your SQL with
CTE’s and Windowing Functions
Clayton Groom
11/15/2013
t: cgroom or SQLMonger
cgroom@mailctp.com
www.geekswithblogs.net/sqlmonger
http://www.linkedin.com/in/claytongroom/
3. Agenda
SQL Basics
Think in Sets
Baseline performance
Save EVERYTHING as you develop (WIP)
Learn what is new and refactor old code
Examples/Scenarios
Begin with the end in mind
–
An example
Common Table Expressions
Windowing functions’
Questions?
4. Objective
Introduce you to new T-SQL language features you are probably not using…
Think in sets
Get your feet wet with new T-SQL functionality
Common Table Expressions (CTE’s)
Windowing functions
Teach SQL-only techniques for aggregation
Rolling aggregates
MTD, QTD, YTD, Same Period PY, etc.
4
5. Think in Sets
Improve your SQL Skills to improve your applications
Procedural approaches are out
– Cursors should almost never be used
– Existing cursor can be “fixed” by changing to the best cursor
type for the situation.
Diagram your queries before you write them
– Venn
– Tree
Set based approaches include:
– Correlated sub queries
– Common Table Expressions (CTE’s)
– MERGE operator
– Outer Apply
5
7. SQL Development 101
Baseline performance
Use DBCC FREEPROCCACHE to clear the procedure cache and
provide solid baseline results
Use Statistics IO and Statistics Time to capture query stats.
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
Keep versions of your code, with timings
– Database performance will change as data grows
– Having the options you have already tried available
– May be applicable to different situations
7
8. Common Table Expressions (CTE’s)
ANSI standard way to avoid temp tables
CTE’s are table results objects defined within the scope of a single
statement.
• Use CTE’s in place of Temp tables
• Aggregate results for following steps
• Use CTE to substitute for a VIEW or #temp table
• Enable GROUP BY on derive columns
• Support Recursive joins
• More readable, easier to maintain code – building block approach.
Limitations:
• GROUP BY, HAVING, or aggregate functions are not allowed in the recursive
part of a recursive common table expression
•
Outer joins are not allowed in the recursive part of a recursive common
table expression
8
9. CTE Example
Simple example – Calculate Total and Percent of Total
WITH CTE_Totals
AS (SELECT CustomerKey
,SUM(SalesAmount) AS [Total Cust Sales Amt]
FROM [dbo].[FactInternetSales]
WHERE CustomerKey IN (15954, 27052, 23808)
GROUP BY CustomerKey
)
SELECT f.CustomerKey
, f.ProductKey
, f.SalesAmount
,t.[Total Cust Sales Amt]
,f.SalesAmount / t.[Total Cust Sales Amt]
as [Pct of Total]
FROM [dbo].[FactInternetSales] AS f
INNER JOIN CTE_Totals t
ON f.CustomerKey = t.CustomerKey
WHERE f.CustomerKey IN (15954, 27052, 23808)
9
10. Demo - Common Table Expression
I will post the examples to my SkyDrive and have a link on my Blog. I will be updating the examples
as I come across useful applications. http://sdrv.ms/HZtKYP
10
12. Windowing function Example
Simple example – Calculate Total and Percent of Total
SELECT CustomerKey
,ProductKey
,SalesAmount
,SUM(SalesAmount)
OVER(PARTITION BY CustomerKey)
AS [Cust Sales Amt]
,SUM(SalesAmount)
OVER() AS [Total Sales Amt]
,cast(100.0 * SalesAmount/SUM(SalesAmount)
OVER(PARTITION BY CustomerKey)
as numeric(5,2)) as [Pct of Cust Total]
,cast(100.0 * SalesAmount/SUM(SalesAmount)
OVER()
as numeric(5,2)) as [Pct of Total]
FROM [dbo].[FactInternetSales]
WHERE CustomerKey IN (15954, 27052, 23808)
order by 1,2;
12
13. Window Partition Clause
Sets the “frame” or subset of the rows that will be accessible to the
windowing function
13
14. Window Order Clause
Orders the rows within the Partitioning frame
Required for the ROW and RANGE operators
14
15. Window Framing Clause
Selects rows within a frame, relative to the current row
Requires an ORDER BY clause
sum(sum(f.SalesAmount) )
OVER(PARTITION BY f.productkey, year(f.orderdate),
Month(f.orderdate)
ORDER BY f.productkey, f.orderdate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) as [Sales Amt MTD]
4
Unbounded
Preceding
3
2
1
0
1
Current
Row
2
3
Unbounded
Following
15
16. Window Framing Clause
Supported Options
ROWS UNBOUNDED PRECEDING
ROWS <unsigned integer literal> PRECEDING
ROWS CURRENT ROW
ROWS BETWEEN UNBOUNDED PRECEDING AND <unsigned integer literal> PRECEDING
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
ROWS BETWEEN UNBOUNDED PRECEDING AND <unsigned integer literal> FOLLOWING
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
ROWS BETWEEN <unsigned integer literal> PRECEDING AND <unsigned integer literal> PRECEDING
ROWS BETWEEN <unsigned integer literal> PRECEDING AND CURRENT ROW
ROWS BETWEEN <unsigned integer literal> PRECEDING AND <unsigned integer literal> FOLLOWING
ROWS BETWEEN <unsigned integer literal> PRECEDING AND UNBOUNDED FOLLOWING
ROWS BETWEEN CURRENT ROW AND CURRENT ROW
ROWS BETWEEN CURRENT ROW AND <unsigned integer> FOLLOWING
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
ROWS BETWEEN <unsigned integer literal> FOLLOWING AND <unsigned integer> FOLLOWING
ROWS BETWEEN <unsigned integer literal> FOLLOWING AND UNBOUNDED FOLLOWING
RANGE UNBOUNDED PRECEDING
RANGE CURRENT ROW
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
RANGE BETWEEN CURRENT ROW AND CURRENT ROW
RANGE uses a count of distinct values, where ROWS uses the count of the
rows. Rows with the a “TIE” based on the Order By clause will be merged.
16
17. Windowing Functions - Aggregate
Aggregate Functions that can be used with the OVER Clause
AVG()
CHECKSUM_AGG() - Checksum of values in a group
COUNT(), COUNT_BIG()
MAX()
MIN()
SUM()
STDEV()
STDEVP()
VAR()
VARP()
17
19. Windowing Functions - Analytic
Analytic functions
CUME_DIST()
FIRST_VALUE()
LAST_VALUE()
LEAD()
LAG()
PERCENTILE_CONT()
PERCENTILE_DISC()
PERCENT_RANK()
- Cumulative Distribution
- First value within the ordered partition
- Last value within the ordered partition
- Returns a following value based on an offset
- Returns a prior value based on an offset
- Percentile based on a continuous distribution
- Percentile based on discreet column values
- Relative rank of a row within a group of rows
19
20. Other new Functions
Aggregate Functions that can be used with the OVER Clause
GROUPING()
GROUPING_ID()
- Replaces the COMPUTE clause
- And gives us some new capabilities
20
21. Demonstrations
I will post the examples to my SkyDrive and have a link on my Blog. I will be updating the examples
as I come across useful applications. http://sdrv.ms/HZtKYP
21
22. References
Windows Functions in SQL
https://www.simple-talk.com/sql/t-sql-programming/window-functions-in-sql/
Working with Window Functions in SQL Server
https://www.simple-talk.com/sql/learn-sql-server/working-with-window-functions-in-sqlserver/
SQL Server 2012 Windowing Functions Part 1 of 2: Running and Sliding Aggregates
http://lennilobel.wordpress.com/tag/t-sql-running-aggregates/
SQL Server Books Online – Over Clause
http://technet.microsoft.com/en-us/library/ms189461.aspx
22
Sample files will be posted shortly on my blog/skydrive
Draw out a tree of the tables and their relationships, and what fields you need from each. Plan out any pre-aggregations needed that can be handled as CTE’s, limit results from joins etc.
SQL Geek dilemma: Do I like Kirk or do I like Picard… Can’t recommend these guys books enough. Joe Celko’s SQL Puzzles in DBMS magazine were what really got my career in SQL development started.
Allow for the creation of sliding windows across the rows in the frame, which enables all kinds of possibilities!
RANGE uses a count of distinct values, where ROWS uses the count of the rows. Rows with the a “TIE” based on the Order By clause will be merged.Note that Azure Database (SQL Azure) does not fully support the SQL 2012 windowing functions yet.