Select Title From Employees
/*
rank()
rank()
Returns the rank of each row within the partition of a result set.
The rank of a row is one plus the number of ranks that come before the row in question.
*/
The rank of a row is one plus the number of ranks that come before the row in question.
*/
Select
Rank() OVER (ORDER BY Title) As [Rank]
,Title
From
Employees
Rank() OVER (ORDER BY Title) As [Rank]
,Title
From
Employees
GO
/*
dense_rank()
dense_rank()
Returns the rank of rows within the partition of a result set, WITHOUT ANY GAPS in the ranking.
The rank of a row is one plus the number of distinct ranks that come before the row in question.
*/
The rank of a row is one plus the number of distinct ranks that come before the row in question.
*/
Select
Dense_Rank() OVER (ORDER BY Title) As [DenseRank]
,Title
From
Employees
Dense_Rank() OVER (ORDER BY Title) As [DenseRank]
,Title
From
Employees
GO
/*
row_number()
row_number()
Returns the sequential number of a row within a partition of a result set,
starting at 1 for the first row in each partition.
*/
starting at 1 for the first row in each partition.
*/
Select
Row_Number() OVER (ORDER BY Title) As [RowNumber]
,Title
From
Employees
Row_Number() OVER (ORDER BY Title) As [RowNumber]
,Title
From
Employees
GO
/*
row_number (PARTION BY)
row_number (PARTION BY)
Divides the result set produced by the FROM clause into partitions
to which the ROW_NUMBER function is applied.
*/
to which the ROW_NUMBER function is applied.
*/
Select
Row_Number() OVER (PARTITION BY Title ORDER BY Title) As [RowNumber]
,Title
From
Employees
Row_Number() OVER (PARTITION BY Title ORDER BY Title) As [RowNumber]
,Title
From
Employees
GO
/*
derived table vs common table expression
*/
derived table vs common table expression
*/
Select * From
(Select
FirstName
,LastName
From Employees) As [x];
(Select
FirstName
,LastName
From Employees) As [x];
-- common table expression
With [x] As
(Select
FirstName
,LastName
From Employees)
Select * From [x];
(Select
FirstName
,LastName
From Employees)
Select * From [x];
-- reuse of cte
With [x] As
(Select
FirstName
,LastName
From Employees)
Select * From [x]
Union All
Select * From [x]
(Select
FirstName
,LastName
From Employees)
Select * From [x]
Union All
Select * From [x]
-- a cte can reference itself
With [x] As
(Select
[e].EmployeeId
,[e].ReportsTo
,[e].Title
,0 As [Level]
From
Employees As [e]
Where
[e].ReportsTo is null
Union All
Select
[e].EmployeeId
,[e].ReportsTo
,[e].Title
,[x].Level + 1
From
Employees As [e] JOIN [x] ON [e].ReportsTo = [x].EmployeeId)
Select * From [x]
Order By ReportsTo
(Select
[e].EmployeeId
,[e].ReportsTo
,[e].Title
,0 As [Level]
From
Employees As [e]
Where
[e].ReportsTo is null
Union All
Select
[e].EmployeeId
,[e].ReportsTo
,[e].Title
,[x].Level + 1
From
Employees As [e] JOIN [x] ON [e].ReportsTo = [x].EmployeeId)
Select * From [x]
Order By ReportsTo
-- can cause infinate loop / limit recursion
OPTION (MAXRECURSION 2);
-- more than one common table
With [x] As
(Select
CustomerId
,ContactName
From Customers)
,[y] As
(Select
CustomerId
,Max(OrderDate) As [LastOrder]
From Orders
Group By CustomerId)
Select TOP (10)
[x].ContactName
,[y].LastOrder
From
[x] JOIN [y] ON [x].CustomerId = [y].CustomerId
(Select
CustomerId
,ContactName
From Customers)
,[y] As
(Select
CustomerId
,Max(OrderDate) As [LastOrder]
From Orders
Group By CustomerId)
Select TOP (10)
[x].ContactName
,[y].LastOrder
From
[x] JOIN [y] ON [x].CustomerId = [y].CustomerId
-- named columns
With [x] (LastName, FirstName, Title) As
(Select
LastName As [Name]
,FirstName As [Name]
,Title
From Employees)
Select
[x].*
From
[x]
(Select
LastName As [Name]
,FirstName As [Name]
,Title
From Employees)
Select
[x].*
From
[x]
-- cte to access calculations
With [x] As
(
Select
Row_Number() OVER (ORDER BY Title) As [RowNumber]
,Title
From
Employees
)
Select
[x].[RowNumber]
,[x].Title
,1 As [Page]
From
[x]
Where
[RowNumber] between 1 and 3
Union
Select
[x].[RowNumber]
,[x].Title
,2 As [Page]
From
[x]
Where
[RowNumber] between 3 and 5
(
Select
Row_Number() OVER (ORDER BY Title) As [RowNumber]
,Title
From
Employees
)
Select
[x].[RowNumber]
,[x].Title
,1 As [Page]
From
[x]
Where
[RowNumber] between 1 and 3
Union
Select
[x].[RowNumber]
,[x].Title
,2 As [Page]
From
[x]
Where
[RowNumber] between 3 and 5
GO
/*
NTile()
NTile()
Distributes the rows in an ordered partition into a specified number of groups.
The groups are numbered, starting at one. For each row, NTILE returns the number
of the group to which the row belongs.
*/
The groups are numbered, starting at one. For each row, NTILE returns the number
of the group to which the row belongs.
*/
Select
NTile(4) OVER (ORDER BY ContactName) [Tile]
,ContactName
From
Customers
Where
ContactTitle = 'Owner'
NTile(4) OVER (ORDER BY ContactName) [Tile]
,ContactName
From
Customers
Where
ContactTitle = 'Owner'
-- use NTile for "percentile" - fills one tile at a time, one record at a time
Select
NTile(10) OVER (ORDER BY ContactName) [Tile]
,ContactName
From
Customers
Where
ContactTitle = 'Owner'
NTile(10) OVER (ORDER BY ContactName) [Tile]
,ContactName
From
Customers
Where
ContactTitle = 'Owner'
-- ntile is based on full result set
Select TOP (20)
NTile(10) OVER (ORDER BY ContactName) [Tile]
,ContactName
From
Customers
NTile(10) OVER (ORDER BY ContactName) [Tile]
,ContactName
From
Customers
GO
/*
TOP Insert, Update, Delete
*/
SET NOCOUNT ON
CREATE TABLE [t] (id uniqueidentifier)
Declare @i int; Set @i = 0
While @i < i =" @i">
Declare @i int; Set @i = 0
While @i < i =" @i">
SET NOCOUNT OFF
-- delete 10 when 10+ is possible
Delete Top (10) From [t];
Select Count(*) From [t]
Select Count(*) From [t]
-- update 10 when 10+ is possible
Update Top (10) [t]
Set id = null;
Select * From [t]
Set id = null;
Select * From [t]
-- insert 10 when 10+ is possible
Insert Top (10) [t]
Select id From [t] where id is not null;
Select * From [t]
Select id From [t] where id is not null;
Select * From [t]
DROP TABLE [t]
GO
/*
TOP Select (simple)
*/
Select Top (15)
ProductName
,UnitPrice
From
Products
ProductName
,UnitPrice
From
Products
GO
/*
TOP PERCENT Select WITH TIES
Note: WITH TIES makes sure that any products with price equal to the lowest price
returned are also included in the result set, even if doing this exceeds 10 percent
returned are also included in the result set, even if doing this exceeds 10 percent
*/
SET NOCOUNT ON
-- how many show be 10 percent?
Select Convert(real, Count(*))/Convert(real, 10) From Products
-- "tie" to NTILE calculations
Select Top (10) PERCENT
ProductName
,UnitPrice
From
Products
Order By
UnitPrice Desc
ProductName
,UnitPrice
From
Products
Order By
UnitPrice Desc
GO
Select Top (10) PERCENT WITH TIES
ProductName
,UnitPrice
From
Products
Order By
UnitPrice Desc
ProductName
,UnitPrice
From
Products
Order By
UnitPrice Desc
GO
/*
SET ROWCOUNT
*/
Declare @i int; Set @i = 5
SET ROWCOUNT @i
SET ROWCOUNT @i
-- limit returned rows
Select
ProductName
,UnitPrice
From
Products
ProductName
,UnitPrice
From
Products
SET ROWCOUNT 0
GO
/*
TOP Expressions
*/
Declare @i int; Set @i = 5
-- use a variable
Select TOP (@i)
ProductName
,UnitPrice
From
Products
ProductName
,UnitPrice
From
Products
-- use an equation
Select TOP (10 - 4)
ProductName
,UnitPrice
From
Products
ProductName
,UnitPrice
From
Products
GO
/*
OUTPUT Clause
*/
SET NOCOUNT ON
CREATE TABLE [t] (id uniqueidentifier, name varchar(25))
Insert Into [t]
Select NewId(), 'Jerry Nixon'
Select NewId(), 'Jerry Nixon'
Select * From [t]
Select * From [t] Where name = 'Jerry Nixon'
-- cannot use identity
Insert Into [t]
Select NewId(), 'Jerry Nixon'
Select Scope_Identity()
Select @@identity
Select NewId(), 'Jerry Nixon'
Select Scope_Identity()
Select @@identity
-- output directly
Insert Into [t]
OUTPUT INSERTED.id As [NewId]
Select NewId(), 'Jerry Nixon'
OUTPUT INSERTED.id As [NewId]
Select NewId(), 'Jerry Nixon'
-- output to a table
Declare @Output Table(id uniqueidentifier)
Insert Into [t]
OUTPUT INSERTED.id Into @Output
Select NewId(), 'Jerry Nixon'
Select * from @Output
Insert Into [t]
OUTPUT INSERTED.id Into @Output
Select NewId(), 'Jerry Nixon'
Select * from @Output
-- with Delete
Delete Top (5) from [t]
OUTPUT DELETED.id As [OldId]
OUTPUT DELETED.id As [OldId]
-- with Update
Update Top (5) [t]
Set id = NewId()
OUTPUT DELETED.id As [OldId], INSERTED.id As [NewId]
Set id = NewId()
OUTPUT DELETED.id As [OldId], INSERTED.id As [NewId]
DROP TABLE [t]
-- unreliable subquery, order by potentially ignored
SELECT TOP 99 PERCENT * FROM Customers
ORDER BY CompanyName
ORDER BY CompanyName
SELECT * FROM
(SELECT TOP 99 PERCENT * FROM Customers ORDER BY CompanyName) AS SubTable
(SELECT TOP 99 PERCENT * FROM Customers ORDER BY CompanyName) AS SubTable
GO
/*
Table-Valued User-Defined-Functions
*/
CREATE FUNCTION MyTableFunction (@id int)
RETURNS @Return Table(EmployeeId int, Title varchar(25))
Begin
Insert Into @Return
Select
EmployeeId
,Title
From Employees
Where
EmployeeId = IsNull(@id, EmployeeId);
Return;
End
RETURNS @Return Table(EmployeeId int, Title varchar(25))
Begin
Insert Into @Return
Select
EmployeeId
,Title
From Employees
Where
EmployeeId = IsNull(@id, EmployeeId);
Return;
End
-- simple use (no dbo prefix)
Select * From MyTableFunction(null)
Select * From MyTableFunction(1)
-- fails with join
Select
[e].EmployeeId
,[f].Title As [TitleFromFunction]
,[e].FirstName
,[e].LastName
From
Employees [e]
JOIN MyTableFunction([e].EmployeeId) As [f] ON [f].EmployeeId = [e].EmployeeId
[e].EmployeeId
,[f].Title As [TitleFromFunction]
,[e].FirstName
,[e].LastName
From
Employees [e]
JOIN MyTableFunction([e].EmployeeId) As [f] ON [f].EmployeeId = [e].EmployeeId
-- success with apply
Select
[e].EmployeeId
,[f].Title As [TitleFromFunction]
,[e].FirstName
,[e].LastName
From
Employees As [e]
CROSS APPLY MyTableFunction([e].EmployeeId) As [f]
[e].EmployeeId
,[f].Title As [TitleFromFunction]
,[e].FirstName
,[e].LastName
From
Employees As [e]
CROSS APPLY MyTableFunction([e].EmployeeId) As [f]
DROP FUNCTION MyTableFunction
/*
.WRITE in the update clause like substring
*/
.WRITE in the update clause like substring
*/
CREATE TABLE TempDemoTable (BigCol varchar(max))
Insert into TempDemoTable (BigCol)
Select 'Now is the time for all good men to come to the aid of their country';
Select * from TempDemoTable;
Insert into TempDemoTable (BigCol)
Select 'Now is the time for all good men to come to the aid of their country';
Select * from TempDemoTable;
-- note: partial updates to large value data types using the .WRITE clause are minimally logged
Update TempDemoTable
Set BigCol .WRITE ('women', 29, 3);
Select * from TempDemoTable;
Set BigCol .WRITE ('women', 29, 3);
Select * from TempDemoTable;
-- length is null
Update TempDemoTable
Set BigCol .WRITE ('women', 29, null);
Select * from TempDemoTable;
Set BigCol .WRITE ('women', 29, null);
Select * from TempDemoTable;
-- expression is null
Update TempDemoTable
Set BigCol .WRITE (null, 29, 3);
Select * from TempDemoTable;
Set BigCol .WRITE (null, 29, 3);
Select * from TempDemoTable;
-- offset is null
Update TempDemoTable
Set BigCol .WRITE (getdate(), null, null);
Select * from TempDemoTable;
Set BigCol .WRITE (getdate(), null, null);
Select * from TempDemoTable;
DROP TABLE TempDemoTable
/*
PIVOT
*/
SET NOCOUNT ON
CREATE TABLE [t] (Teacher varchar(25), Student varchar(25), Grade int, Gender char(1))
Insert Into [t] Select 'Ms. Smith', 'Johnny', 2, 'm';
Insert Into [t] Select 'Ms. Smith', 'Jimmy', 1, 'm';
Insert Into [t] Select 'Ms. Smith', 'Sally', 4, 'f';
Insert Into [t] Select 'Ms. Smith', 'Susan', 4, 'f';
Insert Into [t] Select 'Ms. Smith', 'Martin', 2, 'm';
Insert Into [t] Select 'Ms. Smith', 'Mary', 3, 'f';
Insert Into [t] Select 'Ms. Jones', 'Anna', 3, 'f';
Insert Into [t] Select 'Ms. Jones', 'Jenny', 3, 'f';
Insert Into [t] Select 'Ms. Jones', 'Waldo', 4, 'm';
Insert Into [t] Select 'Ms. Jones', 'Karl', 2, 'm';
Insert Into [t] Select 'Ms. Jones', 'Lucy', 4, 'f';
Insert Into [t] Select 'Ms. Smith', 'Kelly', 3, 'f';
Insert Into [t] Select 'Ms. Smith', 'Jimmy', 1, 'm';
Insert Into [t] Select 'Ms. Smith', 'Sally', 4, 'f';
Insert Into [t] Select 'Ms. Smith', 'Susan', 4, 'f';
Insert Into [t] Select 'Ms. Smith', 'Martin', 2, 'm';
Insert Into [t] Select 'Ms. Smith', 'Mary', 3, 'f';
Insert Into [t] Select 'Ms. Jones', 'Anna', 3, 'f';
Insert Into [t] Select 'Ms. Jones', 'Jenny', 3, 'f';
Insert Into [t] Select 'Ms. Jones', 'Waldo', 4, 'm';
Insert Into [t] Select 'Ms. Jones', 'Karl', 2, 'm';
Insert Into [t] Select 'Ms. Jones', 'Lucy', 4, 'f';
Insert Into [t] Select 'Ms. Smith', 'Kelly', 3, 'f';
print 'Raw data'
Select Teacher, Student, Grade, Gender from [t]
print 'Average grade by teacher'
Select
Teacher
,Avg(Convert(decimal, Grade)) As [Average Grade]
From [t]
Group By Teacher
Teacher
,Avg(Convert(decimal, Grade)) As [Average Grade]
From [t]
Group By Teacher
print 'Classroom size by teacher'
Select
Teacher
,Count(Student) As [Classroom Size]
From [t]
Group By Teacher
Teacher
,Count(Student) As [Classroom Size]
From [t]
Group By Teacher
print 'Grade distribution by teacher'
Select Teacher, [1] As [D], [2] As [C], [3] As [B], [4] As [A] From
(Select Teacher, Grade From [t]) As Data
Pivot (Count(Grade) For grade in ([1], [2], [3], [4])) As PivotTable
Order by Teacher
(Select Teacher, Grade From [t]) As Data
Pivot (Count(Grade) For grade in ([1], [2], [3], [4])) As PivotTable
Order by Teacher
print 'Gender distribution'
Select Gender, [Ms. Smith] As [Ms. Smith], [Ms. Jones] As [Ms. Jones] From
(Select Teacher, Grade, Case Gender When 'f' Then 'Girls' When 'm' Then 'Boys' End As Gender From [t]) As Data
Pivot (Count(grade) For teacher in ([Ms. Smith], [Ms. Jones])) As PivotTable
Order by Gender
(Select Teacher, Grade, Case Gender When 'f' Then 'Girls' When 'm' Then 'Boys' End As Gender From [t]) As Data
Pivot (Count(grade) For teacher in ([Ms. Smith], [Ms. Jones])) As PivotTable
Order by Gender
print 'Average gender grade '
Select Teacher, [m] As [Boys], [f] As [Girls] From
(Select Teacher, Convert(decimal, Grade) Grade, Gender From [t]) As Data
Pivot (Avg(grade) For gender in ([m], [f])) As PivotTable
Order by Teacher
(Select Teacher, Convert(decimal, Grade) Grade, Gender From [t]) As Data
Pivot (Avg(grade) For gender in ([m], [f])) As PivotTable
Order by Teacher
print 'Grade distribution by gender'
Select Gender, [1] As [D], [2] As [C], [3] As [B], [4] As [A] From
(Select Teacher, Grade, Case Gender When 'f' Then 'Girls' When 'm' Then 'Boys' End As Gender From [t]) As Data
Pivot (Count(Teacher) For grade in ([1], [2], [3], [4])) As PivotTable
Order by Gender
(Select Teacher, Grade, Case Gender When 'f' Then 'Girls' When 'm' Then 'Boys' End As Gender From [t]) As Data
Pivot (Count(Teacher) For grade in ([1], [2], [3], [4])) As PivotTable
Order by Gender
GO
DROP TABLE [t]
/*
FAST hint
*/
FAST hint
*/
SELECT * FROM Customers
OPTION(FAST 10)
OPTION(FAST 10)
/*
Error Handling
*/
-- old school, could not prevent exception display
select 4/0
if (@@error = 8134)
print 'Error Encountered'
print 'Execution Continues'
if (@@error = 8134)
print 'Error Encountered'
print 'Execution Continues'
-- try catch
begin try
select 4/0
print 'Execution Halts'
end try
begin catch
print @@error
print error_message()
print ' error caught'
end catch
select 4/0
print 'Execution Halts'
end try
begin catch
print @@error
print error_message()
print ' error caught'
end catch
-- compile error
BEGIN TRY
PRINT 'Inside Try-Block'
SELECT ** FROM T /* will cause syntax error */
END TRY
BEGIN CATCH
print @@error
print error_message()
print ' error caught'
END CATCH
PRINT 'Inside Try-Block'
SELECT ** FROM T /* will cause syntax error */
END TRY
BEGIN CATCH
print @@error
print error_message()
print ' error caught'
END CATCH
-- "lower" error (compile not until execution)
BEGIN TRY
PRINT 'Inside Try-Block'
EXEC ('SELECT ** FROM T ') /* compile error in the lower scope */
END TRY
BEGIN CATCH
print @@error
print error_message()
print ' error caught'
END CATCH
PRINT 'Inside Try-Block'
EXEC ('SELECT ** FROM T ') /* compile error in the lower scope */
END TRY
BEGIN CATCH
print @@error
print error_message()
print ' error caught'
END CATCH
/*
Disable a login
Rename a login
Rename a login
*/
ALTER LOGIN sa DISABLE;
Select * from sys.sql_logins
Select * from sys.sql_logins
ALTER LOGIN sa WITH NAME = [sys-admin];
Select * from sys.sql_logins
Select * from sys.sql_logins
ALTER LOGIN [sys-admin] WITH NAME = sa;
Select * from sys.sql_logins
Select * from sys.sql_logins
ALTER LOGIN sa ENABLE;
Select * from sys.sql_logins
Select * from sys.sql_logins
GO
No comments:
Post a Comment