Você está na página 1de 30

05 | SET Operators, Windows Functions,

and Grouping

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>]

Purchasing

Sales

-- 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

-- 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

INTERSECT

Purchasing

Sales

-- 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
---------11000
11000
11000
11001
11001
11001

OrderDate
-------------------------2007-08-01 00:00:00.000
2007-10-01 00:00:00.000
2006-09-01 00:00:00.000
2007-08-01 00:00:00.000
2006-11-01 00:00:00.000
2007-04-01 00:00:00.000

TotalDue TotalDueByCust
-------- -------------3756.989
9115.1341
2587.8769 9115.1341
2770.2682 9115.1341
2674.0227 7054.1875
3729.364
7054.1875
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

SELECT VendorID, [250] AS Emp1, [251] AS Emp2,


[256] AS Emp3, [257] AS Emp4, [260] AS Emp5
1.FROM
2.(SELECT PurchaseOrderID, EmployeeID, VendorID
3.FROM Purchasing.PurchaseOrderHeader) p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
Grouping
( [250], [251], [256], [257],
[260] )
) AS pvt
SELECTBY
Category,
[2006],[2007],[2008]
ORDER
pvt.VendorID;
FROM ( SELECT Category, Qty, Orderyear
FROM Sales.CategoryQtyYear) AS D
PIVOT(SUM(QTY)
FOR orderyear
VendorID
Emp1 Emp2 Emp3
Emp4 Emp5
-------- IN([2006],[2007],[2008])
----- ----- ----- ----- ----- Spreading
) AS2 pvt;5
1492
4
4
4
1494
2
1496
2
Aggregation

5
4

4
4

5
5

4
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 TerritoryID, CustomerID, SUM(TotalDue) AS
TotalAmountDue
FROM Sales.SalesOrderHeader
GROUP BY
GROUPING SETS((TerritoryID),(CustomerID),());
TerritoryID
CustomerID TotalAmountDue
-------------------------------------SELECT
<column list
with aggregate(s)>
NULL <source>
30116
211671.2674
FROM
NULL BY
30117
919801.8188
GROUP
NULL
313671.5352
GROUPING
SETS( 30118
NULL (<column_name>),--one
NULL
123216786.1159
or
more columns
3
NULL
8913299.2473
(<column_name>),--one
or
more columns
6
NULL
18398929.188
() -- empty
parentheses
if aggregating all rows
9
11814376.0952
); NULL
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.