Você está na página 1de 30

05 | SET Operators, Windows Functions,

and Grouping
Brian Alderman | MCT, CEO / Founder of MicroTechPoint
Tobias Ternstrom | Microsoft SQL Server Program Manager
Querying Microsoft SQL Server 2012 Jump Start
05 | SET Operators, Windows Functions, and Grouping
SET operators, Windows functions, GROUPING sets (PIVOT, UNPIVOT, CUBE, ROLLUP)
06 | Modifying Data
INSERT, UPDATE, and DELETE statements, use of defaults, constraints, and triggers, OUTPUT
07 | Programming with T-SQL
Using T-SQL programming elements, implementing error handling, understanding and implementing transactions
08 | Retrieving SQL Server Metadata and Improving Query Performance
Querying system catalogs and dynamic management views, creating and executing stored procedures, improving SQL
Server query performance
<SELECT query_1>
<set_operator>
<SELECT query_2>
[ORDER BY <sort_list>]
-- only distinct rows from both queries are returned
SELECT ProductID, OrderQty, UnitPrice FROM Sales.SalesOrderDetail
UNION
SELECT ProductID, OrderQty, UnitPrice FROM Purchasing.PurchaseOrderDetail
Purchasing Sales
Purchasing Sales
-- all rows from both queries are returned
SELECT ProductID, OrderQty, UnitPrice FROM Sales.SalesOrderDetail
UNION ALL
SELECT ProductID, OrderQty, UnitPrice FROM Purchasing.PurchaseOrderDetail
Using the INTERSECT operator
Purchasing Sales
INTERSECT
-- only rows that exist in both queries are returned
SELECT ProductID, OrderQty, UnitPrice FROM Sales.SalesOrderDetail
INTERSECT
SELECT ProductID, OrderQty, UnitPrice FROM Purchasing.PurchaseOrderDetail
Using the EXCEPT operator
Sales Purchasing
-- only rows from Sales are returned
SELECT ProductID, OrderQty, UnitPrice FROM Sales.SalesOrderDetail
EXCEPT
SELECT ProductID, OrderQty, UnitPrice FROM Purchasing.PurchaseOrderDetail
1.
2.
SELECT <column_list>
FROM <left_table> AS <alias>
CROSS/OUTER APPLY
<derived_table_expression or inline_TVF> AS <alias>
SELECT CustomerID, OrderDate, TotalDue,
SUM(TotalDue) OVER(PARTITION BY CustomerID)
AS TotalDueByCust
FROM Sales.SalesOrderHeader;
CustomerID OrderDate TotalDue TotalDueByCust
---------- -------------------------- -------- --------------
11000 2007-08-01 00:00:00.000 3756.989 9115.1341
11000 2007-10-01 00:00:00.000 2587.8769 9115.1341
11000 2006-09-01 00:00:00.000 2770.2682 9115.1341
11001 2007-08-01 00:00:00.000 2674.0227 7054.1875
11001 2006-11-01 00:00:00.000 3729.364 7054.1875
11001 2007-04-01 00:00:00.000 650.8008 7054.1875
Function Description
RANK
Returns the rank of each row within the partition of a result
set. May include ties and gaps.
DENSE_RANK
Returns the rank of each row within the partition of a result
set. May include ties but will not include gaps.
ROW_NUMBER
Returns a unique sequential row number within partition
based on current order.
NTILE
Distributes the rows in an ordered partition into a specified
number of groups. Returns the number of the group to which
the current row belongs.
Function Description
LAG
Returns an expression from a previous row that is a defined offset
from the current row. Returns NULL if no row at specified
position.
LEAD
Returns an expression from a later row that is a defined offset
from the current row. Returns NULL if no row at specified
position.
FIRST_VALUE
Returns the first value in the current window frame. Requires
window ordering to be meaningful.
LAST_VALUE
Returns the last value in the current window frame. Requires
window ordering to be meaningful.
Pivoted data
1.
2.
3.
SELECT Category, [2006],[2007],[2008]
FROM ( SELECT Category, Qty, Orderyear
FROM Sales.CategoryQtyYear) AS D
PIVOT(SUM(QTY) FOR orderyear
IN([2006],[2007],[2008])
) AS pvt;
Grouping
Spreading
Aggregation
SELECT VendorID, [250] AS Emp1, [251] AS Emp2,
[256] AS Emp3, [257] AS Emp4, [260] AS Emp5
FROM
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [250], [251], [256], [257], [260] )
) AS pvt
ORDER BY pvt.VendorID;
VendorID Emp1 Emp2 Emp3 Emp4 Emp5
-------- ----- ----- ----- ----- -----
1492 2 5 4 4 4
1494 2 5 4 5 4
1496 2 4 4 5 5
CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int,
Emp3 int, Emp4 int, Emp5 int);
GO
INSERT INTO pvt VALUES (1,4,3,5,4,4);
INSERT INTO pvt VALUES (2,4,1,5,5,5);
INSERT INTO pvt VALUES (3,4,3,5,4,4);
GO

SELECT VendorID, Employee, Orders
FROM
(SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
FROM pvt) p
UNPIVOT
(Orders FOR Employee IN
(Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt;
GO VendorID Employee Orders
1 Emp1 4
1 Emp2 3
Writing queries with grouping sets
SELECT <column list with aggregate(s)>
FROM <source>
GROUP BY
GROUPING SETS(
(<column_name>),--one or more columns
(<column_name>),--one or more columns
() -- empty parentheses if aggregating all rows
);
SELECT TerritoryID, CustomerID, SUM(TotalDue) AS
TotalAmountDue
FROM Sales.SalesOrderHeader
GROUP BY
GROUPING SETS((TerritoryID),(CustomerID),());
TerritoryID CustomerID TotalAmountDue
--------------- ----------- --------------
NULL 30116 211671.2674
NULL 30117 919801.8188
NULL 30118 313671.5352
NULL NULL 123216786.1159
3 NULL 8913299.2473
6 NULL 18398929.188
9 NULL 11814376.0952
1 NULL 18061660.371
7 NULL 8119749.346
CUBE and ROLLUP
SELECT TerritoryID, CustomerID, SUM(TotalDue) AS
TotalAmountDue
FROM Sales.SalesOrderHeader
GROUP BY CUBE(TerritoryID, CustomerID)
ORDER BY TerritoryID, CustomerID;
SELECT TerritoryID, CustomerID, SUM(TotalDue) AS
TotalAmountDue
FROM Sales.SalesOrderHeader
GROUP BY ROLLUP(TerritoryID, CustomerID)
ORDER BY TerritoryID, CustomerID;
<SELECT query_1>
<set_operator>
<SELECT query_2>
[ORDER BY <sort_list>]
-- only distinct rows from both queries are returned
SELECT ProductID, OrderQty, UnitPrice FROM Sales.SalesOrderDetail
UNION
SELECT ProductID, OrderQty, UnitPrice FROM Purchasing.PurchaseOrderDetail
-- all rows from both queries are returned
SELECT ProductID, OrderQty, UnitPrice FROM Sales.SalesOrderDetail
UNION ALL
SELECT ProductID, OrderQty, UnitPrice FROM Purchasing.PurchaseOrderDetail
-- only rows that exist in both queries are returned
SELECT ProductID, OrderQty, UnitPrice FROM Sales.SalesOrderDetail
INTERSECT
SELECT ProductID, OrderQty, UnitPrice FROM Purchasing.PurchaseOrderDetail
-- only rows from Sales are returned
SELECT ProductID, OrderQty, UnitPrice FROM Sales.SalesOrderDetail
EXCEPT
SELECT ProductID, OrderQty, UnitPrice FROM Purchasing.PurchaseOrderDetail
Pivoting data is rotating data from a rows-based orientation to a
columns-based orientation and DISTINCT values from a single
column are displayed across as column headings - may include
aggregation

The GROUPING SETS clause builds on the T-SQL GROUP BY
clause by allowing multiple groups to be defined in the same
query

A CUBE provides a shortcut for defining grouping sets given a
list of columns therefore all possible combinations of GROUPING
SETS are created

A ROLLUP provides a shortcut for defining grouping sets, by
creating combinations with the assumption the input columns
form a hierarchy




2013 Microsoft Corporation. All rights reserved. Microsoft, Windows, Office, Azure, System Center, Dynamics and other product names are or may be registered trademarks and/or trademarks in
the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because
Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information
provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Você também pode gostar