<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="http://code.msdn.microsoft.com/rss.xsl"?><rss version="2.0"><channel><title>Common Solutions for T-SQL Problems</title><link>http://code.msdn.microsoft.com/SQLExamples/Project/ProjectRss.aspx</link><description>Common Data Problems and Solutions Suggested by MSDN Forum Moderators and Answerers</description><item><title>UPDATED WIKI: ExpressMaintenance</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ExpressMaintenance&amp;version=7</link><description>&lt;div class="wikidoc"&gt;
&lt;a name="Top"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;
How to Automate Maintenace Tasks with SQL Server Express
&lt;/h4&gt; &lt;br /&gt;&lt;h6&gt;
&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=ExpressMaintenance&amp;amp;ANCHOR#JonathanKehayias"&gt;Jonathan Kehayias&lt;/a&gt;, May 5, 2008
&lt;/h6&gt; &lt;br /&gt;One of the items missing from SQL Server Express is the ability to schedule jobs to run at set times since it lacks the SQL Server &lt;br /&gt;Agent Service.  This makes scheduling automated maintenance tasks that are easily available in the other editions of SQL Server&lt;br /&gt;through Database Maintenance Plans, difficult at best, but not impossible.  Since the Database Maintenance Plans cover a number&lt;br /&gt;of tasks, they will be broken down individually to allow for implemenation of all or some of the tasks.  &lt;br /&gt; &lt;br /&gt;The commonly used tasks in the Database Maintenance Plan Wizard are:&lt;br /&gt; &lt;br /&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#CheckDB"&gt;Check Database Integrity&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#ShrinkDB"&gt;Shrink Database&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#IndexStats"&gt;Reorganize/Rebuild Indexes/Up Statistics&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#History"&gt;Clean Up History&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ExpressBackups&amp;amp;referringTitle=ExpressMaintenance"&gt;Backup Database (Full, Differential, and/or Transaction Logs)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Cleanup"&gt;Maintenance Cleanup Task&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#OtherSols"&gt;Other Published Solutions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="CheckDB"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Check Database Integrity
&lt;/h6&gt; &lt;br /&gt;Second only to good database backups, validating the integrity of the SQL Databases should be a top priority for anyone running a &lt;br /&gt;SQL Database.  To accomplish this, a simple stored procedure will be created that allows for the database consistency checks to be &lt;br /&gt;run against every database in an instance or a single database only.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
CREATE PROCEDURE [dbo].[CheckDatabaseIntegrity]
(
	@DatabaseName sysname = null
)
AS
 
-- -- Begin Test Code
--DECLARE @DatabaseName sysname
--SET @DatabaseName = 'tempdb'
-- -- End Test Code
 
IF @DatabaseName IS NULL
BEGIN
	EXEC sp_msforeachdb 'DBCC CHECKDB(''?'')'
END
ELSE
	EXEC ('DBCC CHECKDB('''+@DatabaseName+''')'
END
 
 
/*
-- Execute Full Consistency Check of all Databases
sqlcmd -S .\EXPRESS -Q &amp;quot;EXEC CheckDatabaseIntegrity&amp;quot;
 
-- Execute Full Consistency Check of the WebContacts Database
sqlcmd -S .\EXPRESS -Q &amp;quot;EXEC CheckDatabaseIntegrity @DatabaseName='WebContacts'&amp;quot;
 
*/
 
&lt;/pre&gt; &lt;br /&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;a name="ShrinkDB"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Shrink Database
&lt;/h6&gt; &lt;br /&gt;From time to time it is necessary to shrink the size of a database down, perhaps monthly after a data purge process runs.  To allow this, &lt;br /&gt;a shrinking stored procedure will be built.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
CREATE PROCEDURE [dbo].[ShrinkDatabase]
(
	@DatabaseName sysname = null,
	@FreeSpace int = 0
)
AS
 
-- -- Begin Test Code
--DECLARE @DatabaseName sysname
--SET @DatabaseName = 'tempdb'
-- -- End Test Code
 
IF @DatabaseName IS NULL
BEGIN
	EXEC sp_msforeachdb 'DBCC SHRINKDATABASE(''?'', @FreeSpace)'
END
ELSE
	EXEC ('DBCC SHRINKDATABASE('''+@DatabaseName+''', @FreeSpace)'
END
 
 
/*
-- Execute Full Shrink Check of all Databases
sqlcmd -S .\EXPRESS -Q &amp;quot;EXEC ShrinkDatabase&amp;quot;
 
-- Execute Full Shrink of the WebContacts Database
sqlcmd -S .\EXPRESS -Q &amp;quot;EXEC ShrinkDatabase @DatabaseName='WebContacts'&amp;quot;
 
-- Execute Shrink of the WebContacts Database Leaving 10% FreeSpace
sqlcmd -S .\EXPRESS -Q &amp;quot;EXEC ShrinkDatabase @DatabaseName='WebContacts' @FreeSpace=10&amp;quot;
 
*/
 
&lt;/pre&gt; &lt;br /&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;a name="IndexStats"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Perform Index Maintenance
&lt;/h6&gt; &lt;br /&gt;Index Maintenance is crucial to optimum performance of a SQL Server Database.  Microsoft recommends that indexes &lt;br /&gt;containing over 30% fragmentation be rebuilt, while indexes having less than 30% fragmentation be reorganized.  In order &lt;br /&gt;to implement this process in SQL Express, two stored procedures will need to be created.  The first one is a modified version &lt;br /&gt;of a procedure provided by Bill Baer for performing database maintenance on Sharepoint databases, a task that was &lt;br /&gt;unsupported using Database Maintenance Plans with the RTM release of SQL Server.  The reason that his procedure was &lt;br /&gt;chosen for this task is two fold. First, it is provided in a Microsoft Whitepaper, and second, it updates statistics as a part of its &lt;br /&gt;execution.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
USE [master]
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
 
-- =============================================
-- This stored procedure checks all indexes in the current
-- database and performs either offline or online defragmentation
-- according to the specified thresholds.
-- The stored procedure also updates statistics for indexes in which the last update
-- time is older than the specified threshold.
-- Parameters:
--	@onlineDefragThreshold specifies minimum percentage of fragmentation 
--	to perform online defragmentation (default 10%).
--	@offlineDefragThreshold specifies minimum percentage of fragmentation 
--	to perform offline defragmentation (default 30%).
--	@updateStatsThreshold specifies the number of days since the last statistics update
--	which should trigger updating statistics (default 7 days).
-- =============================================
CREATE PROCEDURE [dbo].[sp_DefragIndexes] 
(
	@databaseName sysname = null,
	@onlineDefragThreshold float = 10.0,
	@offlineDefragThreshold float = 30.0,
	@updateStatsThreshold int = 7
)
	
AS
BEGIN
 
IF @databasename is null
BEGIN
	RETURN;
END
 
DECLARE @SQL nvarchar(max)
SET @SQL = 'USE '+ @databasename +'
 
	set nocount on
	DECLARE @objectid int
	DECLARE @indexid int
	DECLARE @frag float
	DECLARE @command varchar(8000)
	DECLARE @schemaname sysname
	DECLARE @objectname sysname
	DECLARE @indexname sysname
 
	declare @AllIndexes table (objectid int, indexid int, fragmentation float)
 
	declare @currentDdbId int
	select @currentDdbId = DB_ID()
	
	insert into @AllIndexes
	SELECT 
		object_id, index_id, avg_fragmentation_in_percent 
	FROM sys.dm_db_index_physical_stats (@currentDdbId, NULL, NULL , NULL, ''LIMITED'')
	WHERE index_id &amp;gt; 0
 
	DECLARE indexesToDefrag CURSOR FOR SELECT * FROM @AllIndexes
 
	OPEN indexesToDefrag;
 
	-- Loop through the partitions.
	FETCH NEXT
	   FROM indexesToDefrag
	   INTO @objectid, @indexid, @frag;
 
	WHILE @@FETCH_STATUS = 0
		BEGIN
 
		SELECT @schemaname = s.name
		FROM sys.objects AS o
		JOIN sys.schemas as s ON s.schema_id = o.schema_id
		WHERE o.object_id = @objectid
 
		SELECT @indexname = name 
		FROM sys.indexes
		WHERE  object_id = @objectid AND index_id = @indexid
 
		IF @frag &amp;gt; @onlineDefragThreshold
		BEGIN 
			IF @frag &amp;lt; @offlineDefragThreshold
				BEGIN;
					SELECT @command = ''ALTER INDEX '' + @indexname + '' ON '' + 
							@schemaname + ''.'' + object_name(@objectid) + 
							'' REORGANIZE''
					EXEC (@command)
				END
 
			IF @frag &amp;gt;= @offlineDefragThreshold
				BEGIN;
					SELECT @command = ''ALTER INDEX '' + 
							@indexname +'' ON '' + @schemaname + ''.'' + 
							object_name(@objectid) + '' REBUILD''
					EXEC (@command)
				END;
			PRINT ''Executed '' + @command
		END
 
		IF STATS_DATE(@objectid, @indexid) &amp;lt; DATEADD(dd, -@updateStatsThreshold, getdate())
		BEGIN
			SELECT @command = ''UPDATE STATISTICS '' + @schemaname + ''.'' + object_name(@objectid) + 
					'' '' + @indexname +'' WITH RESAMPLE''
			EXEC (@command)
 
			PRINT ''Executed '' + @command
		END
 
		FETCH NEXT FROM indexesToDefrag INTO @objectid, @indexid, @frag
 
	END
 
	CLOSE indexesToDefrag;
	DEALLOCATE indexesToDefrag;'
 
DECLARE @Params nvarchar(max)
SET @Params = N'
	@onlineDefragThreshold float,
	@offlineDefragThreshold float,
	@updateStatsThreshold int'
 
EXECUTE sp_executesql @SQL, 
		@Params,
		@onlineDefragThreshold=@onlineDefragThreshold,
		@offlineDefragThreshold=@offlineDefragThreshold,
		@updateStatsThreshold=@updateStatsThreshold;
END
 
 
 
&lt;/pre&gt; &lt;br /&gt;The second procedure is the actual wrapper procedure that will be called from the command line to schedule the database &lt;br /&gt;maintenance.  Like all of the other procedures in this it accepts the database name as an input parameter to allow for &lt;br /&gt;reindexing a single database, but it can also reindex all of the databases on the SQL Server by calling it without the parameter.&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
CREATE PROCEDURE [dbo].[PerformIndexMaintenance]
(
	@DatabaseName sysname = null
)
AS
 
-- -- Begin Test Code
--DECLARE @DatabaseName sysname
--SET @DatabaseName = 'tempdb'
-- -- End Test Code
 
IF @DatabaseName IS NULL
BEGIN
	EXEC sp_msforeachdb N'EXEC sp_DefragIndexes ''[?]'''
END
ELSE
	SET @DatabaseName = '['+REPLACE(REPLACE(@DatabaseName,'[', ''),']','')+']'
	EXEC sp_DefragIndexes @DatabaseName
END
 
 
/*
-- Execute Index Maintenance of all Databases
sqlcmd -S .\EXPRESS -Q &amp;quot;EXEC PerformIndexMaintenance&amp;quot;
 
-- Execute Index Maintenance on the WebContacts Database
sqlcmd -S .\EXPRESS -Q &amp;quot;EXEC PerformIndexMaintenance @DatabaseName='WebContacts'&amp;quot;
 
*/
 
GO
 
&lt;/pre&gt; &lt;br /&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;a name="History"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
History Cleanup
&lt;/h6&gt; &lt;br /&gt;SQL Server tracks the backup history of your server in the msdb database in a series of tables.  The core of this&lt;br /&gt;task in the Database Maintenance Plans is the sp&lt;i&gt;delete&lt;/i&gt;backuphistory procedure in msdb.  A simple wrapper &lt;br /&gt;procedure will be created to call this procedure providing the @oldestdate parameter automatically set to the &lt;br /&gt;current date minus 30 days.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
CREATE PROCEDURE [dbo].[CleanupHistory]
AS
 
DECLARE @OldestDate DATETIME
SET @OldestDate = CONVERT(varchar(10), DATEADD(dd, -30, GETDATE()), 101)
 
EXEC sp_delete_backuphistory @OldestDate
 
/*
-- Execute Cleanup Task
sqlcmd -S .\EXPRESS -Q &amp;quot;EXEC CleanupHistory&amp;quot;
 
*/
 
&lt;/pre&gt; &lt;br /&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="Cleanup"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Maintenance Cleanup Task
&lt;/h6&gt; &lt;br /&gt;This task is used to delete files created by the Maintenance Tasks executing.  Generally it is used to delete backup files from the &lt;br /&gt;backup path that are older than a set number of days.  To accomplish this, a simple VBScript can be created based on the &lt;br /&gt;following code:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;
 
'Start
 
Option Explicit
on error resume next
    Dim oFSO
    Dim sDirectoryPath
    Dim oFolder
    Dim oFileCollection
    Dim oFile
    Dim iDaysOld
    Dim CurDir
    Dim strExtension
 
'Definitions
    iDaysOld = 3
    strExtension = &amp;quot;.bak&amp;quot;
    Set oFSO = CreateObject(&amp;quot;Scripting.FileSystemObject&amp;quot;)
    sDirectoryPath = CreateObject(&amp;quot;WScript.Shell&amp;quot;).CurrentDirectory
    sDirectoryPath = sDirectory &amp;amp; &amp;quot;\&amp;quot;
    set oFolder = oFSO.GetFolder(sDirectoryPath)
    set oFileCollection = oFolder.Files 
 
'Walk through each file in this folder collection. 
    For each oFile in oFileCollection
        If oFile.DateLastModified &amp;lt; (Date() - iDaysOld) Then
  If (strExtension=&amp;quot;&amp;quot;) Or (Right(UCase(oFile.Name), Len(strExtension))=UCase(strExtension)) Then
             oFile.Delete(True)
  End If
        End If
    Next
 
'Clean up
    Set oFSO = Nothing
    Set oFolder = Nothing
    Set oFileCollection = Nothing
    Set oFile = Nothing
'End
 
&lt;/pre&gt; &lt;br /&gt;This code has two variables, extension and number of days which can be set to control what it will delete.  To use it, you simply &lt;br /&gt;create a DeleteFiles.vbs file with this code in it and your needed values in the folder to have the files deleted.  Then schedule a &lt;br /&gt;task to execute this on the necessary schedule using the CScript.exe executable like the following:&lt;br /&gt; &lt;br /&gt;               cscript &amp;quot;C:\BackUp\DeleteFiles.vbs&amp;quot;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="OtherSols"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Other Published Solutions
&lt;/h6&gt; &lt;br /&gt;The above provided information is not the only method of automating these tasks.  After this article was in progress, a post on &lt;br /&gt;the forums made me aware of two articles by Jasper Smith that provide methods for Automating Maintenance in SQL Express.  &lt;br /&gt;They are available on the following links:&lt;br /&gt; &lt;br /&gt;&lt;h6&gt;
Automating Database maintenance in SQL 2005 Express Edition Part I
&lt;/h6&gt;&lt;a href="http://www.sqldbatips.com/showarticle.asp?ID=27" class="externalLink"&gt;http://www.sqldbatips.com/showarticle.asp?ID=27&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Automating Database maintenance in SQL 2005 Express Edition Part II
&lt;/h6&gt;&lt;a href="http://www.sqldbatips.com/showarticle.asp?ID=29" class="externalLink"&gt;http://www.sqldbatips.com/showarticle.asp?ID=29&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;Ola Hallengren has also provided a really nice stored procedure set that were tested against SQL Server Express, and also &lt;br /&gt;provided the following code examples for how to use them with SQL Express:&lt;br /&gt; &lt;br /&gt;&lt;h6&gt;
Backup of system and user databases
&lt;/h6&gt;&lt;pre&gt;
-- Objects needed: DatabaseBackup, CommandExecute, DatabaseSelect
 
sqlcmd -E -S .\SQLEXPRESS -d master -Q &amp;quot;EXECUTE [dbo].[DatabaseBackup] 
@Databases = 'SYSTEM_DATABASES', @Directory = 'C:\Backup', 
@BackupType = 'FULL', @Verify = 'Y', @CleanupTime = 24&amp;quot; -b
 
sqlcmd -E -S .\SQLEXPRESS -d master -Q &amp;quot;EXECUTE [dbo].[DatabaseBackup] 
@Databases = 'USER_DATABASES', @Directory = 'C:\Backup', 
@BackupType = 'FULL', @Verify = 'Y', @CleanupTime = 24&amp;quot; -b
 
sqlcmd -E -S .\SQLEXPRESS -d master -Q &amp;quot;EXECUTE [dbo].[DatabaseBackup] 
@Databases = 'USER_DATABASES', @Directory = 'C:\Backup', 
@BackupType = 'DIFF', @Verify = 'Y', @CleanupTime = 24&amp;quot; -b
 
sqlcmd -E -S .\SQLEXPRESS -d master -Q &amp;quot;EXECUTE [dbo].[DatabaseBackup] 
@Databases = 'USER_DATABASES', @Directory = 'C:\Backup', 
@BackupType = 'LOG', @Verify = 'Y', @CleanupTime = 24&amp;quot; -b
 
&lt;/pre&gt; &lt;br /&gt;&lt;h6&gt;
Integrity check of system and user databases
&lt;/h6&gt;&lt;pre&gt;
--Objects needed: DatabaseIntegrityCheck, CommandExecute, DatabaseSelect
 
sqlcmd -E -S .\SQLEXPRESS -d master -Q &amp;quot;EXECUTE [dbo].[DatabaseIntegrityCheck] 
@Databases = 'SYSTEM_DATABASES'&amp;quot; -b
 
sqlcmd -E -S .\SQLEXPRESS -d master -Q &amp;quot;EXECUTE [dbo].[DatabaseIntegrityCheck] 
@Databases = 'USER_DATABASES'&amp;quot; -b
&lt;/pre&gt; &lt;br /&gt;&lt;h6&gt;
Index Optimization of user databases
&lt;/h6&gt;&lt;pre&gt;
--Objects needed: IndexOptimize, CommandExecute, DatabaseSelect
 
sqlcmd -E -S .\SQLEXPRESS -d master -Q &amp;quot;EXECUTE [dbo].[IndexOptimize]
@Databases = 'USER_DATABASES'&amp;quot; -b
 
&lt;/pre&gt; &lt;br /&gt;All objects are available on his blog and are free to download.&lt;br /&gt;&lt;a href="http://blog.ola.hallengren.com/blog/_archives/2008/1/1/3440068.html" class="externalLink"&gt;http://blog.ola.hallengren.com/blog/_archives/2008/1/1/3440068.html&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;There is also documentation available here.&lt;br /&gt;&lt;a href="http://blog.ola.hallengren.com/_attachments/3440068/Documentation.html" class="externalLink"&gt;http://blog.ola.hallengren.com/_attachments/3440068/Documentation.html&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;h4&gt;
For additional information please see:
&lt;/h4&gt; &lt;br /&gt;&lt;h5&gt;
Books Online References
&lt;/h5&gt; &lt;br /&gt;&lt;h6&gt;
DBCC
&lt;/h6&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms188796.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms188796.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h6&gt;
DBCC CHECKDB
&lt;/h6&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms176064.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms176064.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h6&gt;
DBCC SHRINKDATABASE
&lt;/h6&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms190488.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms190488.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h6&gt;
ALTER INDEX
&lt;/h6&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms188388.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms188388.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h5&gt;
Related Whitepapers and Documents
&lt;/h5&gt; &lt;br /&gt;&lt;h6&gt;
Reorganizing and Rebuilding Indexes
&lt;/h6&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms189858.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms189858.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;h6&gt;
SQL Database Maintenance for Sharepoint Whitepaper
&lt;/h6&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkId=111531&amp;amp;clcid=0x409" class="externalLink"&gt;http://go.microsoft.com/fwlink/?LinkId=111531&amp;amp;clcid=0x409&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Jonathan Kehayias, May 21, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>JonathanKehayias</author><pubDate>Thu, 17 Jul 2008 18:53:52 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: ExpressMaintenance 20080717P</guid></item><item><title>UPDATED WIKI: TestPage</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=TestPage&amp;version=57</link><description>&lt;div class="wikidoc"&gt;
&lt;h5&gt;
Test Environment
&lt;/h5&gt;You may create links here to your new Wiki page in order to work on it and keep it out of Public view until you are ready to make it 'public'. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Then when you are ready to make your page 'Public', note the Wiki PageName, and use it for the Wiki link on the referring page. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;After your page is complete, and you have 'published' it, you may wish to remove the link from this page.&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;WikiLink:  [Words Seen by User|YourWikiPage]&lt;/b&gt;&lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=DetachDatabaseVideo&amp;amp;referringTitle=TestPage"&gt;Detaching A Database with SSMS&lt;/a&gt; - Video Tutorial&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ListPrimaryForeignKeyInTable&amp;amp;referringTitle=TestPage"&gt;Find out all the primary key and foreign key constraints in a table&lt;/a&gt; - Suprotim Agarwal&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=analytics&amp;amp;referringTitle=TestPage"&gt;Testing out analytics&lt;/a&gt; - Suprotim&lt;br /&gt; &lt;br /&gt;This concept 'could' work -requires a counter.cgi hosted somewhere...&lt;br /&gt;(A bit tacky perhaps...)&lt;br /&gt;&lt;div class="video" style="text-align:center"&gt;
&lt;span class="player"&gt;&lt;object type="application/x-shockwave-flash" height="285" width="320" classid="CLSID:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"&gt;
&lt;param name="movie" value="http://www.indiana.edu/~counter/Count.cgi?df=MSDNMod-Page1.dat"&gt;

&lt;/param&gt;&lt;embed type="application/x-shockwave-flash" height="285" width="320" src="http://www.indiana.edu/~counter/Count.cgi?df=MSDNMod-Page1.dat" pluginspage="http://macromedia.com/go/getflashplayer" autoplay="false" autostart="false" /&gt;
&lt;/object&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="external"&gt;&lt;a href="http://www.indiana.edu/~counter/Count.cgi?df=MSDNMod-Page1.dat" target="_blank"&gt;Launch in another window&lt;/a&gt;&lt;/span&gt;
&lt;/div&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=TestPage"&gt;Contributors&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Arnie Rowland, Mar 16, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>ArnieRowland</author><pubDate>Wed, 02 Jul 2008 18:22:13 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: TestPage 20080702P</guid></item><item><title>UPDATED WIKI: NumbersTable</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=NumbersTable&amp;version=9</link><description>&lt;div class="wikidoc"&gt;
&lt;a name="Top"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;
How to Create and Use A Numbers Table
&lt;/h4&gt; &lt;br /&gt;&lt;h6&gt;
&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=NumbersTable&amp;amp;ANCHOR#JonathanKehayias"&gt;Jonathan Kehayias&lt;/a&gt;, April 15, 2008
&lt;/h6&gt; &lt;br /&gt;A Numbers table is simply a table that holds a single integer column with each &lt;br /&gt;positive integer number in the range from the number 1 to the maximum value &lt;br /&gt;of an integer 2,147,483,647.  &lt;b&gt;(Note:  When creating the table off the exact&lt;/b&gt;&lt;br /&gt;&lt;b&gt;code provided in this example below, your Numbers table will be&lt;/b&gt; &lt;br /&gt;&lt;b&gt;roughly 8GB in size.  This is overkill in most cases and you should&lt;/b&gt;&lt;br /&gt;&lt;b&gt;size the number of rows being create according to your own needs.)&lt;/b&gt;  &lt;br /&gt;&lt;a href="#CreateTable"&gt;Creating a Numbers table&lt;/a&gt; is really simple to do and it &lt;br /&gt;can be used to solve a broad number of problems.&lt;br /&gt; &lt;br /&gt;Some Examples of how to use a Numbers Table are:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href="#MissingDates"&gt;Identify Missing Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#DateRange"&gt;Get All Dates Between Two Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#MissingNumbers"&gt;Identify Missing Numeric Values&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#NumberRange"&gt;Get All Numbers Between Two Values&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;br /&gt;These solutions apply to all versions of SQL Server.&lt;br /&gt; &lt;br /&gt;&lt;a name="CreateTable"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Create Number Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create Sample Data using a Table Varable
SELECT TOP 2147483647 IDENTITY(INT,0,1) AS N
INTO Numbers
FROM sysobjects a, sysobjects b, sysobjects c, sysobjects d, sysobjects e
 
-- Create a Primary Key and Clustered Index to control data order
ALTER TABLE dbo.Numbers ADD CONSTRAINT
PK_Numbers PRIMARY KEY CLUSTERED (N) 
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;a name="MissingDates"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Dates In a Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Find the dates not in the table an in the first 14 days of January
SELECT DATEADD(dd, N, '01/01/2007') as MissingDates
FROM Numbers
WHERE n &amp;lt; 14
  AND DATEADD(dd, N, '01/01/2007') NOT IN (SELECT DateField FROM @TestTable)
 
 
/* Results
MissingDates
-----------------------
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-06 00:00:00.000
2007-01-11 00:00:00.000
2007-01-13 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="DateRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Dates Between Two Dates
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Date Range Values
DECLARE @StartDate datetime
DECLARE @EndDate datetime
 
SET @StartDate = '01/01/2007'
SET @EndDate = '01/07/2007'
 
-- Find the dates between these two dates
SELECT DATEADD(dd, N, @StartDate) as DatesBetween
FROM Numbers
WHERE n &amp;lt; (DATEDIFF(dd, @StartDate, @EndDate)+1)
 
 
/* Results
DatesBetween
-----------------------
2007-01-01 00:00:00.000
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-05 00:00:00.000
2007-01-06 00:00:00.000
2007-01-07 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="MissingNumbers"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Numeric Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Delete Odd Numbered Rows From Table
DELETE @TestTable WHERE RowID IN (1,3,5,7)
 
-- Find the missing row Numbers
SELECT N as MissingRows
FROM Numbers
WHERE N &amp;gt; 0 -- RowID's are greater than 0
  AND N &amp;lt;= (SELECT MAX(RowID) FROM @TestTable) -- Constrain to valid RowID's
  AND N NOT IN (SELECT RowID FROM @TestTable) -- RowID not in the table
 
 
/* Results
MissingRows
-----------
1
3
5
7
*/
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="NumberRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Numbers Between Two Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Number Range Values
DECLARE @Start int
DECLARE @End int
 
SET @Start = 14
SET @End = 22
 
-- Find the numbers between these two numbers
SELECT N as NumbersBetween
FROM Numbers
WHERE N BETWEEN @Start AND @End
 
 
/* Results
NumbersBetween
--------------
14
15
16
17
18
19
20
21
22
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Jonathan Kehayias, Apr 15, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>JonathanKehayias</author><pubDate>Wed, 02 Jul 2008 18:18:24 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: NumbersTable 20080702P</guid></item><item><title>UPDATED WIKI: TestPage</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=TestPage&amp;version=56</link><description>&lt;div class="wikidoc"&gt;
&lt;h5&gt;
Test Environment
&lt;/h5&gt;You may create links here to your new Wiki page in order to work on it and keep it out of Public view until you are ready to make it 'public'. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Then when you are ready to make your page 'Public', note the Wiki PageName, and use it for the Wiki link on the referring page. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;After your page is complete, and you have 'published' it, you may wish to remove the link from this page.&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;WikiLink:  [Words Seen by User|YourWikiPage]&lt;/b&gt;&lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=DetachDatabaseVideo&amp;amp;referringTitle=TestPage"&gt;Detaching A Database with SSMS&lt;/a&gt; - Video Tutorial&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ListPrimaryForeignKeyInTable&amp;amp;referringTitle=TestPage"&gt;Find out all the primary key and foreign key constraints in a table&lt;/a&gt; - Suprotim Agarwal&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=analytics&amp;amp;referringTitle=TestPage"&gt;Testing out analytics&lt;/a&gt; - Suprotim&lt;br /&gt; &lt;br /&gt;This concept 'could' work -requires a counter.cgi hosted somewhere...&lt;br /&gt;(A bit tacky perhaps...)&lt;br /&gt;&lt;div class="video" style="text-align:center"&gt;
&lt;span class="player"&gt;&lt;object type="application/x-shockwave-flash" height="285" width="320" classid="CLSID:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"&gt;
&lt;param name="movie" value="http://www.indiana.edu/~counter/Count.cgi?df=mgrwww-cntinfo.dat"&gt;

&lt;/param&gt;&lt;embed type="application/x-shockwave-flash" height="285" width="320" src="http://www.indiana.edu/~counter/Count.cgi?df=mgrwww-cntinfo.dat" pluginspage="http://macromedia.com/go/getflashplayer" autoplay="false" autostart="false" /&gt;
&lt;/object&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="external"&gt;&lt;a href="http://www.indiana.edu/~counter/Count.cgi?df=mgrwww-cntinfo.dat" target="_blank"&gt;Launch in another window&lt;/a&gt;&lt;/span&gt;
&lt;/div&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=TestPage"&gt;Contributors&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Arnie Rowland, Mar 16, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>ArnieRowland</author><pubDate>Wed, 02 Jul 2008 18:16:02 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: TestPage 20080702P</guid></item><item><title>UPDATED WIKI: NumbersTable</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=NumbersTable&amp;version=8</link><description>&lt;div class="wikidoc"&gt;
&lt;a name="Top"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;
How to Create and Use A Numbers Table
&lt;/h4&gt; &lt;br /&gt;&lt;h6&gt;
&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=NumbersTable&amp;amp;ANCHOR#JonathanKehayias"&gt;Jonathan Kehayias&lt;/a&gt;, April 15, 2008
&lt;/h6&gt; &lt;br /&gt;A Numbers table is simply a table that holds a single integer column with each &lt;br /&gt;positive integer number in the range from the number 1 to the maximum value &lt;br /&gt;of an integer 2,147,483,647.  (*Note:  When creating the table off the exact code&lt;br /&gt;provided in this example below, your Numbers table will be roughly 8GB in size.* &lt;br /&gt;&lt;b&gt;This is overkill in most cases and you should size the number of rows being create&lt;/b&gt;&lt;br /&gt;&lt;b&gt;according to your own personal needs.&lt;/b&gt;)  &lt;a href="#CreateTable"&gt;Creating a Numbers table&lt;/a&gt; is really simple to do &lt;br /&gt;and it can be used to solve a broad number of problems.&lt;br /&gt; &lt;br /&gt;Some Examples of how to use a Numbers Table are:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href="#MissingDates"&gt;Identify Missing Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#DateRange"&gt;Get All Dates Between Two Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#MissingNumbers"&gt;Identify Missing Numeric Values&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#NumberRange"&gt;Get All Numbers Between Two Values&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;br /&gt;These solutions apply to all versions of SQL Server.&lt;br /&gt; &lt;br /&gt;&lt;a name="CreateTable"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Create Number Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create Sample Data using a Table Varable
SELECT TOP 2147483647 IDENTITY(INT,0,1) AS N
INTO Numbers
FROM sysobjects a, sysobjects b, sysobjects c, sysobjects d, sysobjects e
 
-- Create a Primary Key and Clustered Index to control data order
ALTER TABLE dbo.Numbers ADD CONSTRAINT
PK_Numbers PRIMARY KEY CLUSTERED (N) 
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;a name="MissingDates"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Dates In a Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Find the dates not in the table an in the first 14 days of January
SELECT DATEADD(dd, N, '01/01/2007') as MissingDates
FROM Numbers
WHERE n &amp;lt; 14
  AND DATEADD(dd, N, '01/01/2007') NOT IN (SELECT DateField FROM @TestTable)
 
 
/* Results
MissingDates
-----------------------
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-06 00:00:00.000
2007-01-11 00:00:00.000
2007-01-13 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="DateRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Dates Between Two Dates
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Date Range Values
DECLARE @StartDate datetime
DECLARE @EndDate datetime
 
SET @StartDate = '01/01/2007'
SET @EndDate = '01/07/2007'
 
-- Find the dates between these two dates
SELECT DATEADD(dd, N, @StartDate) as DatesBetween
FROM Numbers
WHERE n &amp;lt; (DATEDIFF(dd, @StartDate, @EndDate)+1)
 
 
/* Results
DatesBetween
-----------------------
2007-01-01 00:00:00.000
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-05 00:00:00.000
2007-01-06 00:00:00.000
2007-01-07 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="MissingNumbers"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Numeric Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Delete Odd Numbered Rows From Table
DELETE @TestTable WHERE RowID IN (1,3,5,7)
 
-- Find the missing row Numbers
SELECT N as MissingRows
FROM Numbers
WHERE N &amp;gt; 0 -- RowID's are greater than 0
  AND N &amp;lt;= (SELECT MAX(RowID) FROM @TestTable) -- Constrain to valid RowID's
  AND N NOT IN (SELECT RowID FROM @TestTable) -- RowID not in the table
 
 
/* Results
MissingRows
-----------
1
3
5
7
*/
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="NumberRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Numbers Between Two Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Number Range Values
DECLARE @Start int
DECLARE @End int
 
SET @Start = 14
SET @End = 22
 
-- Find the numbers between these two numbers
SELECT N as NumbersBetween
FROM Numbers
WHERE N BETWEEN @Start AND @End
 
 
/* Results
NumbersBetween
--------------
14
15
16
17
18
19
20
21
22
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Jonathan Kehayias, Apr 15, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>JonathanKehayias</author><pubDate>Wed, 02 Jul 2008 18:15:19 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: NumbersTable 20080702P</guid></item><item><title>UPDATED WIKI: NumbersTable</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=NumbersTable&amp;version=7</link><description>&lt;div class="wikidoc"&gt;
&lt;a name="Top"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;
How to Create and Use A Numbers Table
&lt;/h4&gt; &lt;br /&gt;&lt;h6&gt;
&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=NumbersTable&amp;amp;ANCHOR#JonathanKehayias"&gt;Jonathan Kehayias&lt;/a&gt;, April 15, 2008
&lt;/h6&gt; &lt;br /&gt;A Numbers table is simply a table that holds a single integer column with each &lt;br /&gt;positive integer number in the range from the number 1 to the maximum value &lt;br /&gt;of an integer 2,147,483,647.  (&lt;b&gt;Note:&lt;/b&gt;  &lt;b&gt;When&lt;/b&gt; &lt;b&gt;creating&lt;/b&gt; &lt;b&gt;the&lt;/b&gt; &lt;b&gt;table&lt;/b&gt; &lt;b&gt;off&lt;/b&gt; &lt;b&gt;the&lt;/b&gt; &lt;b&gt;exact&lt;/b&gt; &lt;b&gt;code&lt;/b&gt;&lt;br /&gt;*provided in this example below, your Numbers table will be roughly 8GB in size. &lt;br /&gt;This is overkill in most cases and you should size the number of rows being create&lt;br /&gt;according to your own personal needs.*)  &lt;a href="#CreateTable"&gt;Creating a Numbers table&lt;/a&gt; is really simple to do &lt;br /&gt;and it can be used to solve a broad number of problems.&lt;br /&gt; &lt;br /&gt;Some Examples of how to use a Numbers Table are:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href="#MissingDates"&gt;Identify Missing Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#DateRange"&gt;Get All Dates Between Two Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#MissingNumbers"&gt;Identify Missing Numeric Values&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#NumberRange"&gt;Get All Numbers Between Two Values&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;br /&gt;These solutions apply to all versions of SQL Server.&lt;br /&gt; &lt;br /&gt;&lt;a name="CreateTable"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Create Number Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create Sample Data using a Table Varable
SELECT TOP 2147483647 IDENTITY(INT,0,1) AS N
INTO Numbers
FROM sysobjects a, sysobjects b, sysobjects c, sysobjects d, sysobjects e
 
-- Create a Primary Key and Clustered Index to control data order
ALTER TABLE dbo.Numbers ADD CONSTRAINT
PK_Numbers PRIMARY KEY CLUSTERED (N) 
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;a name="MissingDates"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Dates In a Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Find the dates not in the table an in the first 14 days of January
SELECT DATEADD(dd, N, '01/01/2007') as MissingDates
FROM Numbers
WHERE n &amp;lt; 14
  AND DATEADD(dd, N, '01/01/2007') NOT IN (SELECT DateField FROM @TestTable)
 
 
/* Results
MissingDates
-----------------------
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-06 00:00:00.000
2007-01-11 00:00:00.000
2007-01-13 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="DateRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Dates Between Two Dates
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Date Range Values
DECLARE @StartDate datetime
DECLARE @EndDate datetime
 
SET @StartDate = '01/01/2007'
SET @EndDate = '01/07/2007'
 
-- Find the dates between these two dates
SELECT DATEADD(dd, N, @StartDate) as DatesBetween
FROM Numbers
WHERE n &amp;lt; (DATEDIFF(dd, @StartDate, @EndDate)+1)
 
 
/* Results
DatesBetween
-----------------------
2007-01-01 00:00:00.000
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-05 00:00:00.000
2007-01-06 00:00:00.000
2007-01-07 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="MissingNumbers"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Numeric Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Delete Odd Numbered Rows From Table
DELETE @TestTable WHERE RowID IN (1,3,5,7)
 
-- Find the missing row Numbers
SELECT N as MissingRows
FROM Numbers
WHERE N &amp;gt; 0 -- RowID's are greater than 0
  AND N &amp;lt;= (SELECT MAX(RowID) FROM @TestTable) -- Constrain to valid RowID's
  AND N NOT IN (SELECT RowID FROM @TestTable) -- RowID not in the table
 
 
/* Results
MissingRows
-----------
1
3
5
7
*/
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="NumberRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Numbers Between Two Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Number Range Values
DECLARE @Start int
DECLARE @End int
 
SET @Start = 14
SET @End = 22
 
-- Find the numbers between these two numbers
SELECT N as NumbersBetween
FROM Numbers
WHERE N BETWEEN @Start AND @End
 
 
/* Results
NumbersBetween
--------------
14
15
16
17
18
19
20
21
22
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Jonathan Kehayias, Apr 15, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>JonathanKehayias</author><pubDate>Wed, 02 Jul 2008 18:14:48 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: NumbersTable 20080702P</guid></item><item><title>UPDATED WIKI: NumbersTable</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=NumbersTable&amp;version=6</link><description>&lt;div class="wikidoc"&gt;
&lt;a name="Top"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;
How to Create and Use A Numbers Table
&lt;/h4&gt; &lt;br /&gt;&lt;h6&gt;
&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=NumbersTable&amp;amp;ANCHOR#JonathanKehayias"&gt;Jonathan Kehayias&lt;/a&gt;, April 15, 2008
&lt;/h6&gt; &lt;br /&gt;A Numbers table is simply a table that holds a single integer column with each &lt;br /&gt;positive integer number in the range from the number 1 to the maximum value &lt;br /&gt;of an integer 2,147,483,647.  (&lt;b&gt;bold&lt;/b&gt;Note:  When creating the table off the exact code&lt;br /&gt;provided in this example below, your Numbers table will be roughly 8GB in size. &lt;br /&gt;This is overkill in most cases and you should size the number of rows being create&lt;br /&gt;according to your own personal needs.*)  &lt;a href="#CreateTable"&gt;Creating a Numbers table&lt;/a&gt; is really simple to do &lt;br /&gt;and it can be used to solve a broad number of problems.&lt;br /&gt; &lt;br /&gt;Some Examples of how to use a Numbers Table are:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href="#MissingDates"&gt;Identify Missing Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#DateRange"&gt;Get All Dates Between Two Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#MissingNumbers"&gt;Identify Missing Numeric Values&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#NumberRange"&gt;Get All Numbers Between Two Values&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;br /&gt;These solutions apply to all versions of SQL Server.&lt;br /&gt; &lt;br /&gt;&lt;a name="CreateTable"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Create Number Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create Sample Data using a Table Varable
SELECT TOP 2147483647 IDENTITY(INT,0,1) AS N
INTO Numbers
FROM sysobjects a, sysobjects b, sysobjects c, sysobjects d, sysobjects e
 
-- Create a Primary Key and Clustered Index to control data order
ALTER TABLE dbo.Numbers ADD CONSTRAINT
PK_Numbers PRIMARY KEY CLUSTERED (N) 
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;a name="MissingDates"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Dates In a Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Find the dates not in the table an in the first 14 days of January
SELECT DATEADD(dd, N, '01/01/2007') as MissingDates
FROM Numbers
WHERE n &amp;lt; 14
  AND DATEADD(dd, N, '01/01/2007') NOT IN (SELECT DateField FROM @TestTable)
 
 
/* Results
MissingDates
-----------------------
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-06 00:00:00.000
2007-01-11 00:00:00.000
2007-01-13 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="DateRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Dates Between Two Dates
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Date Range Values
DECLARE @StartDate datetime
DECLARE @EndDate datetime
 
SET @StartDate = '01/01/2007'
SET @EndDate = '01/07/2007'
 
-- Find the dates between these two dates
SELECT DATEADD(dd, N, @StartDate) as DatesBetween
FROM Numbers
WHERE n &amp;lt; (DATEDIFF(dd, @StartDate, @EndDate)+1)
 
 
/* Results
DatesBetween
-----------------------
2007-01-01 00:00:00.000
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-05 00:00:00.000
2007-01-06 00:00:00.000
2007-01-07 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="MissingNumbers"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Numeric Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Delete Odd Numbered Rows From Table
DELETE @TestTable WHERE RowID IN (1,3,5,7)
 
-- Find the missing row Numbers
SELECT N as MissingRows
FROM Numbers
WHERE N &amp;gt; 0 -- RowID's are greater than 0
  AND N &amp;lt;= (SELECT MAX(RowID) FROM @TestTable) -- Constrain to valid RowID's
  AND N NOT IN (SELECT RowID FROM @TestTable) -- RowID not in the table
 
 
/* Results
MissingRows
-----------
1
3
5
7
*/
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="NumberRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Numbers Between Two Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Number Range Values
DECLARE @Start int
DECLARE @End int
 
SET @Start = 14
SET @End = 22
 
-- Find the numbers between these two numbers
SELECT N as NumbersBetween
FROM Numbers
WHERE N BETWEEN @Start AND @End
 
 
/* Results
NumbersBetween
--------------
14
15
16
17
18
19
20
21
22
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Jonathan Kehayias, Apr 15, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>JonathanKehayias</author><pubDate>Wed, 02 Jul 2008 18:14:01 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: NumbersTable 20080702P</guid></item><item><title>UPDATED WIKI: NumbersTable</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=NumbersTable&amp;version=5</link><description>&lt;div class="wikidoc"&gt;
&lt;a name="Top"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;
How to Create and Use A Numbers Table
&lt;/h4&gt; &lt;br /&gt;&lt;h6&gt;
&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=NumbersTable&amp;amp;ANCHOR#JonathanKehayias"&gt;Jonathan Kehayias&lt;/a&gt;, April 15, 2008
&lt;/h6&gt; &lt;br /&gt;A Numbers table is simply a table that holds a single integer column with each &lt;br /&gt;positive integer number in the range from the number 1 to the maximum value &lt;br /&gt;of an integer 2,147,483,647.  (*Note:  When creating the table off the exact code&lt;br /&gt;provided in this example below, your Numbers table will be roughly 8GB in size. &lt;br /&gt;This is overkill in most cases and you should size the number of rows being create&lt;br /&gt;according to your own personal needs.*)  &lt;a href="#CreateTable"&gt;Creating a Numbers table&lt;/a&gt; is really simple to do &lt;br /&gt;and it can be used to solve a broad number of problems.&lt;br /&gt; &lt;br /&gt;Some Examples of how to use a Numbers Table are:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href="#MissingDates"&gt;Identify Missing Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#DateRange"&gt;Get All Dates Between Two Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#MissingNumbers"&gt;Identify Missing Numeric Values&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#NumberRange"&gt;Get All Numbers Between Two Values&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;br /&gt;These solutions apply to all versions of SQL Server.&lt;br /&gt; &lt;br /&gt;&lt;a name="CreateTable"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Create Number Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create Sample Data using a Table Varable
SELECT TOP 2147483647 IDENTITY(INT,0,1) AS N
INTO Numbers
FROM sysobjects a, sysobjects b, sysobjects c, sysobjects d, sysobjects e
 
-- Create a Primary Key and Clustered Index to control data order
ALTER TABLE dbo.Numbers ADD CONSTRAINT
PK_Numbers PRIMARY KEY CLUSTERED (N) 
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;a name="MissingDates"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Dates In a Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Find the dates not in the table an in the first 14 days of January
SELECT DATEADD(dd, N, '01/01/2007') as MissingDates
FROM Numbers
WHERE n &amp;lt; 14
  AND DATEADD(dd, N, '01/01/2007') NOT IN (SELECT DateField FROM @TestTable)
 
 
/* Results
MissingDates
-----------------------
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-06 00:00:00.000
2007-01-11 00:00:00.000
2007-01-13 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="DateRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Dates Between Two Dates
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Date Range Values
DECLARE @StartDate datetime
DECLARE @EndDate datetime
 
SET @StartDate = '01/01/2007'
SET @EndDate = '01/07/2007'
 
-- Find the dates between these two dates
SELECT DATEADD(dd, N, @StartDate) as DatesBetween
FROM Numbers
WHERE n &amp;lt; (DATEDIFF(dd, @StartDate, @EndDate)+1)
 
 
/* Results
DatesBetween
-----------------------
2007-01-01 00:00:00.000
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-05 00:00:00.000
2007-01-06 00:00:00.000
2007-01-07 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="MissingNumbers"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Numeric Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Delete Odd Numbered Rows From Table
DELETE @TestTable WHERE RowID IN (1,3,5,7)
 
-- Find the missing row Numbers
SELECT N as MissingRows
FROM Numbers
WHERE N &amp;gt; 0 -- RowID's are greater than 0
  AND N &amp;lt;= (SELECT MAX(RowID) FROM @TestTable) -- Constrain to valid RowID's
  AND N NOT IN (SELECT RowID FROM @TestTable) -- RowID not in the table
 
 
/* Results
MissingRows
-----------
1
3
5
7
*/
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="NumberRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Numbers Between Two Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Number Range Values
DECLARE @Start int
DECLARE @End int
 
SET @Start = 14
SET @End = 22
 
-- Find the numbers between these two numbers
SELECT N as NumbersBetween
FROM Numbers
WHERE N BETWEEN @Start AND @End
 
 
/* Results
NumbersBetween
--------------
14
15
16
17
18
19
20
21
22
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Jonathan Kehayias, Apr 15, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>JonathanKehayias</author><pubDate>Wed, 02 Jul 2008 18:13:43 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: NumbersTable 20080702P</guid></item><item><title>UPDATED WIKI: NumbersTable</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=NumbersTable&amp;version=4</link><description>&lt;div class="wikidoc"&gt;
&lt;a name="Top"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;
How to Create and Use A Numbers Table
&lt;/h4&gt; &lt;br /&gt;&lt;h6&gt;
&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=NumbersTable&amp;amp;ANCHOR#JonathanKehayias"&gt;Jonathan Kehayias&lt;/a&gt;, April 15, 2008
&lt;/h6&gt; &lt;br /&gt;A Numbers table is simply a table that holds a single integer column with each &lt;br /&gt;positive integer number in the range from the number 1 to the maximum value &lt;br /&gt;of an integer 2,147,483,647.  *(Note:  When creating the table off the exact code&lt;br /&gt;provided in this example below, your Numbers table will be roughly 8GB in size. &lt;br /&gt;This is overkill in most cases and you should size the number of rows being create&lt;br /&gt;according to your own personal needs.)*  &lt;a href="#CreateTable"&gt;Creating a Numbers table&lt;/a&gt; is really simple to do &lt;br /&gt;and it can be used to solve a broad number of problems.&lt;br /&gt; &lt;br /&gt;Some Examples of how to use a Numbers Table are:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href="#MissingDates"&gt;Identify Missing Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#DateRange"&gt;Get All Dates Between Two Dates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#MissingNumbers"&gt;Identify Missing Numeric Values&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#NumberRange"&gt;Get All Numbers Between Two Values&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;br /&gt;These solutions apply to all versions of SQL Server.&lt;br /&gt; &lt;br /&gt;&lt;a name="CreateTable"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
Create Number Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create Sample Data using a Table Varable
SELECT TOP 2147483647 IDENTITY(INT,0,1) AS N
INTO Numbers
FROM sysobjects a, sysobjects b, sysobjects c, sysobjects d, sysobjects e
 
-- Create a Primary Key and Clustered Index to control data order
ALTER TABLE dbo.Numbers ADD CONSTRAINT
PK_Numbers PRIMARY KEY CLUSTERED (N) 
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;a name="MissingDates"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Dates In a Table
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Find the dates not in the table an in the first 14 days of January
SELECT DATEADD(dd, N, '01/01/2007') as MissingDates
FROM Numbers
WHERE n &amp;lt; 14
  AND DATEADD(dd, N, '01/01/2007') NOT IN (SELECT DateField FROM @TestTable)
 
 
/* Results
MissingDates
-----------------------
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-06 00:00:00.000
2007-01-11 00:00:00.000
2007-01-13 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="DateRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Dates Between Two Dates
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Date Range Values
DECLARE @StartDate datetime
DECLARE @EndDate datetime
 
SET @StartDate = '01/01/2007'
SET @EndDate = '01/07/2007'
 
-- Find the dates between these two dates
SELECT DATEADD(dd, N, @StartDate) as DatesBetween
FROM Numbers
WHERE n &amp;lt; (DATEDIFF(dd, @StartDate, @EndDate)+1)
 
 
/* Results
DatesBetween
-----------------------
2007-01-01 00:00:00.000
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-04 00:00:00.000
2007-01-05 00:00:00.000
2007-01-06 00:00:00.000
2007-01-07 00:00:00.000
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="MissingNumbers"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Identify Missing Numeric Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Create a table variable for the test data
DECLARE @TestTable TABLE
(RowID int identity primary key,
 DateField datetime)
 
-- Add some dates to the table
INSERT INTO @TestTable VALUES ('01/01/2007')
INSERT INTO @TestTable VALUES ('01/05/2007')
INSERT INTO @TestTable VALUES ('01/07/2007')
INSERT INTO @TestTable VALUES ('01/08/2007')
INSERT INTO @TestTable VALUES ('01/09/2007')
INSERT INTO @TestTable VALUES ('01/10/2007')
INSERT INTO @TestTable VALUES ('01/12/2007')
INSERT INTO @TestTable VALUES ('01/14/2007')
 
-- Delete Odd Numbered Rows From Table
DELETE @TestTable WHERE RowID IN (1,3,5,7)
 
-- Find the missing row Numbers
SELECT N as MissingRows
FROM Numbers
WHERE N &amp;gt; 0 -- RowID's are greater than 0
  AND N &amp;lt;= (SELECT MAX(RowID) FROM @TestTable) -- Constrain to valid RowID's
  AND N NOT IN (SELECT RowID FROM @TestTable) -- RowID not in the table
 
 
/* Results
MissingRows
-----------
1
3
5
7
*/
 
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a name="NumberRange"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h6&gt;
 Get All Numbers Between Two Values
&lt;/h6&gt;&lt;pre&gt;
-- Suppress data loading messages
SET NOCOUNT ON
 
-- Set Number Range Values
DECLARE @Start int
DECLARE @End int
 
SET @Start = 14
SET @End = 22
 
-- Find the numbers between these two numbers
SELECT N as NumbersBetween
FROM Numbers
WHERE N BETWEEN @Start AND @End
 
 
/* Results
NumbersBetween
--------------
14
15
16
17
18
19
20
21
22
*/
&lt;/pre&gt;&lt;a href="#Top"&gt;Return to Top&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Jonathan Kehayias, Apr 15, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>JonathanKehayias</author><pubDate>Wed, 02 Jul 2008 18:12:55 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: NumbersTable 20080702P</guid></item><item><title>UPDATED WIKI: TestPage</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=TestPage&amp;version=55</link><description>&lt;div class="wikidoc"&gt;
&lt;h5&gt;
Test Environment
&lt;/h5&gt;You may create links here to your new Wiki page in order to work on it and keep it out of Public view until you are ready to make it 'public'. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Then when you are ready to make your page 'Public', note the Wiki PageName, and use it for the Wiki link on the referring page. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;After your page is complete, and you have 'published' it, you may wish to remove the link from this page.&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;WikiLink:  [Words Seen by User|YourWikiPage]&lt;/b&gt;&lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=DetachDatabaseVideo&amp;amp;referringTitle=TestPage"&gt;Detaching A Database with SSMS&lt;/a&gt; - Video Tutorial&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ListPrimaryForeignKeyInTable&amp;amp;referringTitle=TestPage"&gt;Find out all the primary key and foreign key constraints in a table&lt;/a&gt; - Suprotim Agarwal&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=analytics&amp;amp;referringTitle=TestPage"&gt;Testing out analytics&lt;/a&gt; - Suprotim&lt;br /&gt; &lt;br /&gt;&lt;div class="video" style="text-align:center"&gt;
&lt;span class="player"&gt;&lt;object type="application/x-shockwave-flash" height="285" width="320" classid="CLSID:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"&gt;
&lt;param name="movie" value="http://www.indiana.edu/~counter/Count.cgi?df=mgrwww-cntinfo.dat"&gt;

&lt;/param&gt;&lt;embed type="application/x-shockwave-flash" height="285" width="320" src="http://www.indiana.edu/~counter/Count.cgi?df=mgrwww-cntinfo.dat" pluginspage="http://macromedia.com/go/getflashplayer" autoplay="false" autostart="false" /&gt;
&lt;/object&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="external"&gt;&lt;a href="http://www.indiana.edu/~counter/Count.cgi?df=mgrwww-cntinfo.dat" target="_blank"&gt;Launch in another window&lt;/a&gt;&lt;/span&gt;
&lt;/div&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=TestPage"&gt;Contributors&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Arnie Rowland, Mar 16, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>ArnieRowland</author><pubDate>Wed, 02 Jul 2008 18:03:05 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: TestPage 20080702P</guid></item><item><title>UPDATED WIKI: TestPage</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=TestPage&amp;version=54</link><description>&lt;div class="wikidoc"&gt;
&lt;h5&gt;
Test Environment
&lt;/h5&gt;You may create links here to your new Wiki page in order to work on it and keep it out of Public view until you are ready to make it 'public'. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Then when you are ready to make your page 'Public', note the Wiki PageName, and use it for the Wiki link on the referring page. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;After your page is complete, and you have 'published' it, you may wish to remove the link from this page.&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;WikiLink:  [Words Seen by User|YourWikiPage]&lt;/b&gt;&lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=DetachDatabaseVideo&amp;amp;referringTitle=TestPage"&gt;Detaching A Database with SSMS&lt;/a&gt; - Video Tutorial&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ListPrimaryForeignKeyInTable&amp;amp;referringTitle=TestPage"&gt;Find out all the primary key and foreign key constraints in a table&lt;/a&gt; - Suprotim Agarwal&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=analytics&amp;amp;referringTitle=TestPage"&gt;Testing out analytics&lt;/a&gt; - Suprotim&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=TestPage"&gt;Contributors&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Arnie Rowland, Mar 16, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>SuprotimAgarwal</author><pubDate>Tue, 01 Jul 2008 18:22:28 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: TestPage 20080701P</guid></item><item><title>UPDATED WIKI: HowWiki</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=HowWiki&amp;version=25</link><description>&lt;div class="wikidoc"&gt;
&lt;h5&gt;
Ten Steps to Create Wiki Pages
&lt;/h5&gt;&lt;ol&gt;
&lt;li&gt;All Wiki Pages link to a Parent page. The Wiki Entry page (SQLExamples) is the 'top level' parent page (or &lt;i&gt;Resource&lt;/i&gt; Page).&lt;/li&gt;&lt;li&gt;Navigate to the Page that will contain the Link to the Wiki Page you wish to Create. While you are developing your page you will most likely use the [TestEnvironment] page for the Link. Place the Link on the [TestEnvironment] page. After you have completed your page and reviewed it, you may move the link to the [Home] page.&lt;/li&gt;&lt;li&gt;Then Click on the [Edit] button -located under the [Home] tab.&lt;/li&gt;&lt;li&gt;Designate the text that you will use as the 'hotlink' on the page -The 'hotlink' can be a new or existing Word(s) or Sentence.&lt;/li&gt;&lt;li&gt;Insert the Page Link in this Format [Words Seen by User|PageName]. You can designate multiple words to be seen by the user, then a 'pipe' symbol (Vertical Bar), then the WikiPage Name. All enclosed in square brackets. No Spaces in the WikiPage name, and the Wiki page will NOT be created at this point.&lt;/li&gt;&lt;li&gt;Preview the page to verify that it appears as you desire.&lt;/li&gt;&lt;li&gt;&lt;i&gt;&lt;b&gt;SAVE&lt;/b&gt;&lt;/i&gt; the page. Preview does NOT save the page. If you navigate away without saving, your changes will be lost.&lt;/li&gt;&lt;li&gt;After you have saved the page, it will display with your changes. Click on the designated 'hotlink'.&lt;/li&gt;&lt;li&gt;You will be taken to a 'PlaceHolder' page that informs you that the Wiki page does not exist -BUT will exist if you Click on the [Edit] button and create content. Here is a &lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=NewPage&amp;amp;referringTitle=HowWiki"&gt;test&lt;/a&gt; -please DO NOT edit or save the NewPage. Click on [HowWiki] in the 'breadcrumb' to return here.&lt;/li&gt;&lt;li&gt;Click the [Edit] on the PlaceHolder page, Add your content, View in the Preview Window, when satisfied set the 'Parent Wiki Page' to 'Home', and click on the [Save] Button.&lt;/li&gt;
&lt;/ol&gt;Your New Wiki Page is now 'on-line'.&lt;br /&gt; &lt;br /&gt;There is complete Page Version control -for &lt;i&gt;Saved&lt;/i&gt; Pages. &lt;br /&gt;If you make a mistake, you can click on the [Page Info] tab, &lt;br /&gt;Select and View the previous Pages Until you find the Page Version you want to restore, &lt;br /&gt;Click on the [Edit] button for that Page Version, and &lt;br /&gt;Then Click on the [Save] button. It then becomes the Current Page Version.&lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Arnie Rowland, Mar 14, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>ArnieRowland</author><pubDate>Fri, 27 Jun 2008 13:48:08 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: HowWiki 20080627P</guid></item><item><title>UPDATED WIKI: ListPrimaryForeignKeyInTable</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ListPrimaryForeignKeyInTable&amp;version=6</link><description>&lt;div class="wikidoc"&gt;
&lt;h4&gt;
Find out all the primary key and foreign key constraints in a table
&lt;/h4&gt;&lt;h6&gt;
&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=ListPrimaryForeignKeyInTable&amp;amp;ANCHOR#SuprotimAgarwal"&gt;Suprotim Agarwal&lt;/a&gt;, May 6, 2008
&lt;/h6&gt; &lt;br /&gt;SQL Server 2005 exposes meta data using either the Catalog or the Information&lt;i&gt;Schema Views. The question that arises is when to use what. The Catalog views help retrieve the meta data information on both the database and the server level in an efficient manner. The Information&lt;/i&gt;Schema views have been quiet optimized in Sql Server 2005 and is also a good alternative to access the metadata. Another advantage of using this view is that it is SQL-92 compatible and will work with other databases that support SQL-92 standards.&lt;br /&gt; &lt;br /&gt;In this article, we will see how to use the Information Schema views to find out the primary and foreign key constraints in a table. &lt;br /&gt; &lt;br /&gt;&lt;b&gt;SQL Server 2005 Solution&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;
 
// To view the primary and foreign key constraints on a particular table in the AdventureWorks database
 
USE ADVENTUREWORKS
GO
 
SELECT 
   Table_Name as [TableName], 
   Column_Name as [ColumnName],
   Constraint_Name as [Constraint], 
   Table_Schema as [Schema]
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE Table_Name = 'Address'
ORDER BY 
   [TableName], 
   [ColumnName]
 
 
// To view the primary and foreign key constraints on all tables in the AdventureWorks database
 
USE ADVENTUREWORKS
GO
 
SELECT 
   Table_Name as [TableName], 
   Column_Name as [ColumnName],
   Constraint_Name as [Constraint], 
   Table_Schema as [Schema]
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
ORDER BY 
   [TableName], 
   [ColumnName]
 
&lt;/pre&gt; &lt;br /&gt;&lt;b&gt;SQL Server 2008 Solution&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;
 
// To view the primary and foreign key constraints on a particular table in the AdventureWorks database
 
USE ADVENTUREWORKS
GO
 
SELECT 
   Table_Name as [TableName], 
   Column_Name as [ColumnName],
   Constraint_Name as [Constraint], 
   Table_Schema as [Schema]
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE Table_Name = 'Address'
ORDER BY 
   [TableName], 
   [ColumnName]
 
 
// To view the primary and foreign key constraints on all tables in the AdventureWorks database
 
USE ADVENTUREWORKS
GO
 
SELECT 
   Table_Name as [TableName], 
   Column_Name as [ColumnName],
   Constraint_Name as [Constraint], 
   Table_Schema as [Schema]
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
ORDER BY 
   [TableName], 
   [ColumnName]
 
&lt;/pre&gt; &lt;br /&gt;_____________________________________________________________________________________________________________&lt;br /&gt; &lt;br /&gt;&lt;i&gt;Page Created By: Suprotim Agarwal, May 6, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>SuprotimAgarwal</author><pubDate>Thu, 26 Jun 2008 09:10:20 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: ListPrimaryForeignKeyInTable 20080626A</guid></item><item><title>UPDATED WIKI: RecursiveCTE</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=RecursiveCTE&amp;version=10</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
Exploring Recursive Common Table Expressions (CTE)
&lt;/h1&gt;&lt;h6&gt;
&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=RecursiveCTE&amp;amp;ANCHOR#SuprotimAgarwal"&gt;Suprotim Agarwal&lt;/a&gt;, June 26, 2008
&lt;/h6&gt; &lt;br /&gt;A Common Table Expression(CTE) is an ANSI SQL-99 temporary result set that can be declared once and referenced multiple times in a query. It acts as a replacement for many sub-queries and thereby improves query simplicity and performance in most cases.&lt;br /&gt; &lt;br /&gt;If you are new to CTE's, I would recommend you to check this link &lt;a href="http://msdn.microsoft.com/en-us/library/ms190766.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms190766.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;  before you proceed ahead with Recursive CTE's.&lt;br /&gt; &lt;br /&gt;A recursive CTE is one in which a CTE refers to itself in the CTE definition to obtain subsets of data until the complete result set is obtained. Recursive CTE's come in quiet handy when you need to represent hierarchical data and query against it. Infact,  the raw power of a CTE is realized when it is used recursively to obtain a resultset. In previous versions of SQL Server, you could create recursive queries using cursors and temporary tables.&lt;br /&gt; &lt;br /&gt;The syntax of a recursive query would be similar to the following:&lt;br /&gt; &lt;br /&gt;WITH cte-nm (&lt;i&gt;column&lt;/i&gt;1, column&lt;i&gt;2, ...&lt;/i&gt;)  &lt;br /&gt;AS  &lt;br /&gt;( &lt;br /&gt;cte-query-definition   -- Anchor member&lt;br /&gt;UNION ALL &lt;br /&gt;cte-query-definition –- Recursive member which references cte_name&lt;br /&gt;)  &lt;br /&gt;SELECT * FROM cte-nm  &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;In this sample, we will see how to use Recursive CTE's to find out the level of a team member in a project.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Case Scenario&lt;/b&gt; : Let us assume that we have a table called ProjectMemberDetails. We need to display the 'Level' of each TeamMember in that project. The level of each team member will be ascertained by the hierarchy of Managers above the person.&lt;br /&gt; &lt;br /&gt;For the sake of demonstrating Recursive CTE's, we will create the following columns in the ProjectMemberDetails table - ID, TeamMemNm, Designation and ManagerID. Using Recursive CTE's, we will then calculate the level of each team member in the team. Level 1 is the highest grade, given only to those who do not have managers above them; in our case the EngagementManager.&lt;br /&gt; &lt;br /&gt;The hierarchy of a project team for demonstratation purposes is as follows:&lt;br /&gt; &lt;br /&gt;EngagementManager - 1&lt;br /&gt;Sr. Project Manager - 2&lt;br /&gt;Project Manager - 3&lt;br /&gt;Project Leader - 4&lt;br /&gt;Team Leader - 5&lt;br /&gt;Sr. Developer - 6&lt;br /&gt;Developer/Tester - 7&lt;br /&gt; &lt;br /&gt;The code to display the hierarchy would be as follows:&lt;br /&gt; &lt;br /&gt;&lt;b&gt;SQL Server 2005/SQL Server 2008&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;
DROP TABLE #ProjectMemberDetails
-- create temporary table called ProjectMemberDetails
CREATE TABLE #ProjectMemberDetails
(
ID int Identity(1,1) PRIMARY KEY,
TeamMemNm varchar(100),
Designation varchar(50),
ManagerID int NULL
)
 
-- Insert some sample records in the ProjectMemberDetails table
INSERT INTO #ProjectMemberDetails VALUES('Tim','Engagement Manager',NULL);
INSERT INTO #ProjectMemberDetails VALUES('Kathy','Sr. Project Manager',1);
INSERT INTO #ProjectMemberDetails VALUES('Levonca','Project Manager',2);
INSERT INTO #ProjectMemberDetails VALUES('Sid','Project Manager',2);
INSERT INTO #ProjectMemberDetails VALUES('Carrie','Project Leader',3);
INSERT INTO #ProjectMemberDetails VALUES('Cristina','Project Leader',4);
INSERT INTO #ProjectMemberDetails VALUES('Santi','Team Leader',5);
INSERT INTO #ProjectMemberDetails VALUES('Michelle','Team Leader',5);
INSERT INTO #ProjectMemberDetails VALUES('Pablo','Team Leader',6);
INSERT INTO #ProjectMemberDetails VALUES('Mario','Team Leader',6);
INSERT INTO #ProjectMemberDetails VALUES('Anand','Sr. Developer',7);
INSERT INTO #ProjectMemberDetails VALUES('Bill','Sr. Developer',7);
INSERT INTO #ProjectMemberDetails VALUES('Jack','Sr. Developer',8);
INSERT INTO #ProjectMemberDetails VALUES('Tibre','Sr. Developer',8);
INSERT INTO #ProjectMemberDetails VALUES('Lisa','Sr. Developer',9);
INSERT INTO #ProjectMemberDetails VALUES('Scott','Sr. Tester',10);
INSERT INTO #ProjectMemberDetails VALUES('Nancy','Developer',11);
INSERT INTO #ProjectMemberDetails VALUES('MJ','Developer',12);
INSERT INTO #ProjectMemberDetails VALUES('Ziak','Developer',13);
INSERT INTO #ProjectMemberDetails VALUES('Martin','Developer',14);
INSERT INTO #ProjectMemberDetails VALUES('David','Developer',14);
INSERT INTO #ProjectMemberDetails VALUES('Steve','Developer',15);
INSERT INTO #ProjectMemberDetails VALUES('Rachael','Developer',15);
INSERT INTO #ProjectMemberDetails VALUES('Sally','Tester',16);
INSERT INTO #ProjectMemberDetails VALUES('Peter','Tester',16);
SELECT * FROM #ProjectMemberDetails;
 
-- Use Recursive CTE to find out the Level of each ProjectMemberDetails
-- in the project
WITH CTE(ID, TeamMemberName, Designation, ManagerID, ProjectLevel)
AS
(
SELECT ID, TeamMemNm, Designation, ManagerID, 1 as ProjectLevel
From #ProjectMemberDetails WHERE ManagerID is NULL
UNION ALL
SELECT e.ID, e.TeamMemNm, e.Designation, e.ManagerID, c.ProjectLevel + 1
FROM #ProjectMemberDetails e
INNER JOIN CTE c
ON e.ManagerID = c.ID
)
SELECT ID, TeamMemberName, Designation, ManagerID, ProjectLevel
FROM CTE Order BY ID
 
 
&lt;/pre&gt; &lt;br /&gt;Here's a break up of the query:&lt;br /&gt; &lt;br /&gt;1. In the query below, the anchor member returns the person who is at the highest level in the project (Engagement Manager) and marks the level as 1&lt;br /&gt; &lt;br /&gt;SELECT ID, TeamMemNm, Designation, ManagerID, 1 as ProjectLevel&lt;br /&gt;From #ProjectMemberDetails WHERE ManagerID is NULL&lt;br /&gt; &lt;br /&gt;2.  To determine the person directly below him (EngagementManager), a join is made between the ProjectMemberDetails table and the CTE, which helps in determining the member which is directly below the person returned by the anchor member. In our case, that would be the Project Manager.  &lt;br /&gt; &lt;br /&gt;3. With every recursive invocation, we get the output (c.ProjectLevel + 1) for the join e.ManagerID = c.ID&lt;br /&gt; &lt;br /&gt;The final result set consists of the union of all the subsets generated by the anchor and recursive members. The result set is displayed below.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Result&lt;/b&gt;&lt;br /&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;&lt;th&gt;TeamMemberName&lt;/th&gt;&lt;th&gt;Designation&lt;/th&gt;&lt;th&gt;ManagerID&lt;/th&gt;&lt;th&gt;ProjectLevel&lt;/th&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;&lt;td&gt;	Tim&lt;/td&gt;&lt;td&gt;	Engagement Manager&lt;/td&gt;&lt;td&gt; NULL&lt;/td&gt;&lt;td&gt;	1&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;&lt;td&gt;	Kathy&lt;/td&gt;&lt;td&gt;        Sr. Project Manager	&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;	2&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;&lt;td&gt;	Levonca&lt;/td&gt;&lt;td&gt;	Project Manager&lt;/td&gt;&lt;td&gt;	2&lt;/td&gt;&lt;td&gt;	3&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;&lt;td&gt;	Sid&lt;/td&gt;&lt;td&gt;	Project Manager&lt;/td&gt;&lt;td&gt;	2&lt;/td&gt;&lt;td&gt;	3&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;&lt;td&gt;	Carrie&lt;/td&gt;&lt;td&gt;	Project Leader&lt;/td&gt;&lt;td&gt;	3&lt;/td&gt;&lt;td&gt;	4&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;&lt;td&gt;	Cristina&lt;/td&gt;&lt;td&gt;	Project Leader&lt;/td&gt;&lt;td&gt;	4&lt;/td&gt;&lt;td&gt;	4&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;&lt;td&gt;	Santi	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;&lt;td&gt;	Michelle	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;&lt;td&gt;	Pablo	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;&lt;td&gt;	Mario	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;&lt;td&gt;	Anand	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;&lt;td&gt;	Bill	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;&lt;td&gt;	Jack	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	8&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;&lt;td&gt;	Tibre	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	8&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;&lt;td&gt;	Lisa	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	9&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;&lt;td&gt;	Scott	&lt;/td&gt;&lt;td&gt;Sr. Tester&lt;/td&gt;&lt;td&gt;               10&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;17&lt;/td&gt;&lt;td&gt;	Nancy	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	11&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;&lt;td&gt;	MJ	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	12&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;&lt;td&gt;	Ziak	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	13&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;&lt;td&gt;	Martin	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	14&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;&lt;td&gt;	David	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	14&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;22&lt;/td&gt;&lt;td&gt;	Steve	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	15&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;23&lt;/td&gt;&lt;td&gt;	Rachael	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	15&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;&lt;td&gt;	Sally	&lt;/td&gt;&lt;td&gt;Tester&lt;/td&gt;&lt;td&gt;	                16&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;25&lt;/td&gt;&lt;td&gt;	Peter	&lt;/td&gt;&lt;td&gt;Tester&lt;/td&gt;&lt;td&gt;	                 16&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt; &lt;br /&gt;References: &lt;a href="http://msdn.microsoft.com/en-us/library/ms186243.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms186243.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>SuprotimAgarwal</author><pubDate>Thu, 26 Jun 2008 09:08:24 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: RecursiveCTE 20080626A</guid></item><item><title>UPDATED WIKI: TestPage</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=TestPage&amp;version=53</link><description>&lt;div class="wikidoc"&gt;
&lt;h5&gt;
Test Environment
&lt;/h5&gt;You may create links here to your new Wiki page in order to work on it and keep it out of Public view until you are ready to make it 'public'. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Then when you are ready to make your page 'Public', note the Wiki PageName, and use it for the Wiki link on the referring page. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;After your page is complete, and you have 'published' it, you may wish to remove the link from this page.&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;WikiLink:  [Words Seen by User|YourWikiPage]&lt;/b&gt;&lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=DetachDatabaseVideo&amp;amp;referringTitle=TestPage"&gt;Detaching A Database with SSMS&lt;/a&gt; - Video Tutorial&lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ListPrimaryForeignKeyInTable&amp;amp;referringTitle=TestPage"&gt;Find out all the primary key and foreign key constraints in a table&lt;/a&gt; - Suprotim Agarwal&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=TestPage"&gt;Contributors&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created By: Arnie Rowland, Mar 16, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>SuprotimAgarwal</author><pubDate>Thu, 26 Jun 2008 09:06:27 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: TestPage 20080626A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=Home&amp;version=95</link><description>&lt;div class="wikidoc"&gt;
&lt;h3&gt;
Common Solutions for T-SQL Problems
&lt;/h3&gt;&lt;h6&gt;
&lt;i&gt;Information presented in this WIKI represents the suggestions, ideas, and opinions of Volunteer &lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ContributorBios&amp;amp;referringTitle=Home"&gt;Moderators and Answerers&lt;/a&gt; who support the Microsoft MSDN SQL Server Forums. (Unless specifically stated otherwise, nothing should be construed to represent the official positions or opinions of Microsoft and/or its Employees.)&lt;/i&gt;
&lt;/h6&gt; &lt;br /&gt;Please direct any additional Questions to the &lt;a href="http://forums.microsoft.com/Forums/default.aspx?ForumGroupID=19&amp;amp;SiteID=1" class="externalLink"&gt;MSDN SQL Server Related Forums&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;-----------------------------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;How can I &lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=PrepareQuestion&amp;amp;referringTitle=Home"&gt;Prepare My Question&lt;/a&gt; to Increase the Possibility of Getting a Good Solution?&lt;br /&gt;What are the &lt;a href="http://www.microsoft.com/communities/conduct/default.mspx" class="externalLink"&gt;Rules of Conduct&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt; expected on the Forums?&lt;br /&gt;-----------------------------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt; &lt;br /&gt;&lt;h5&gt;
&lt;b&gt;&lt;u&gt;&lt;i&gt;How To&lt;/i&gt; Examples of Selected T-SQL Programming Constructs&lt;/u&gt;&lt;/b&gt;
&lt;/h5&gt; &lt;br /&gt;&lt;b&gt;Data Related Queries&lt;/b&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=AuditOrBypassTriggerExecution&amp;amp;referringTitle=Home"&gt;Audit or Bypass Trigger Execution&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=CreateACommaDelimitedList&amp;amp;referringTitle=Home"&gt;Create a Comma Delimited List&lt;/a&gt; from a Column in a Table&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=NumbersTable&amp;amp;referringTitle=Home"&gt;Create and Use A Numbers Table&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ResultsByRange&amp;amp;referringTitle=Home"&gt;Control Return Results by Range&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=PurgeAllTables&amp;amp;referringTitle=Home"&gt;Delete All Data From All User Tables In A Database&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=RecursiveCTE&amp;amp;referringTitle=Home"&gt;Exploring Recursive Common Table Expressions (CTE)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=DuplicateRows&amp;amp;referringTitle=Home"&gt;Find and/or Delete Duplicate Rows&lt;/a&gt; in a Table&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=FindDataBetweenDates&amp;amp;referringTitle=Home"&gt;Find Rows of Data Between Two Dates&lt;/a&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=FirstAvailableTimeslot&amp;amp;referringTitle=Home"&gt;Find First Available Timeslot&lt;/a&gt; for Scheduling &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=FindMissingListItems&amp;amp;referringTitle=Home"&gt;Find the Missing Parts of a List &lt;/a&gt; of Requirements&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=Implementation%20of%20DDL%20Trigger%20in%20SQL%20Server%202005&amp;amp;referringTitle=Home"&gt;Implementation of DDL Trigger in SQL Server 2005&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=IncrementAlphaNumericValues&amp;amp;referringTitle=Home"&gt;Increment an AlphaNumeric Value&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ISNULL_COALESCE&amp;amp;referringTitle=Home"&gt;Use ISNULL() and COALESCE()&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=GetAppLock&amp;amp;referringTitle=Home"&gt;Lock a Stored Procedure for Single Use Only&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=QueryBasedUponAbsenceOfData&amp;amp;referringTitle=Home"&gt;Query an Object Whose Result Set Depends Upon the Lack of Data In Another Object&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=StringArrayInput&amp;amp;referringTitle=Home"&gt;Pass and Handle a Delimited String&lt;/a&gt; similar to handling an Array() of Values&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=PIVOTData&amp;amp;referringTitle=Home"&gt;PIVOT Data Using T-SQL&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=RankValuesInGroups&amp;amp;referringTitle=Home"&gt;Rank Values in Groups&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=NonDynamicSearch&amp;amp;referringTitle=Home"&gt;Search all or partial columns without Dynamic SQL&lt;/a&gt; while avoiding SQL Injection&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=DynamicSearch&amp;amp;referringTitle=Home"&gt;Search all or partial columns with Dynamic SQL&lt;/a&gt; while avoiding SQL Injection&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=SelectTopNbyGroup&amp;amp;referringTitle=Home"&gt;SELECT TOP n by Group&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=UNPIVOTData&amp;amp;referringTitle=Home"&gt;UNPIVOT Data Using T-SQL&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Maintenance Queries&lt;/b&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ExpressBackups&amp;amp;referringTitle=Home"&gt;Automate Backups in SQL Express&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=DetachUserDatabases&amp;amp;referringTitle=Home"&gt;Detach All User Databases&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=LastBackUpDate&amp;amp;referringTitle=Home"&gt;Find Last BackUp Date Of All Databases On Your Server&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=AgentLongRunning&amp;amp;referringTitle=Home"&gt;Find Long Running Agent Jobs&lt;/a&gt; &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=LongRunningProcs&amp;amp;referringTitle=Home"&gt;Find the TOP n Longest Running Procedures&lt;/a&gt; (or Queries), Ordered by Total Impact on Server &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ExpressMaintenance&amp;amp;referringTitle=Home"&gt;Performing Common Maintenance Tasks in SQL Express&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=TransferLogins&amp;amp;referringTitle=Home"&gt;Transfer Logins to Another Server&lt;/a&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;SQL Server 2008&lt;/b&gt;&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=Manage%20unstructured%20data%20using%20FILESTREAM%20Feature%20in%20SQL%20Server%202008&amp;amp;referringTitle=Home"&gt;Manage unstructured data using FILESTREAM Feature in SQL Server 2008&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;-----------------------------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;h5&gt;
&lt;b&gt;&lt;u&gt;&lt;i&gt;How To&lt;/i&gt; Troubleshoot and Debug T-SQL Code&lt;/u&gt;&lt;/b&gt;
&lt;/h5&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=Troubleshoot%20Deadlocking%20in%20SQL%20Server&amp;amp;referringTitle=Home"&gt;Troubleshoot Deadlocking in SQL Server&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=Troubleshoot%20Deadlocking%20in%20SQL%20Server%202005%20using%20Profiler&amp;amp;referringTitle=Home"&gt;Troubleshoot Deadlocking in SQL Server 2005 using Profiler&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=Profiler&amp;amp;referringTitle=Home"&gt;Using the SQL Server Profiler&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;-----------------------------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;h5&gt;
&lt;b&gt;&lt;u&gt;Writing Transact-SQL Statements Tutorial&lt;/u&gt;&lt;/b&gt;
&lt;/h5&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms365303.aspx" class="externalLink"&gt;http://msdn2.microsoft.com/en-us/library/ms365303.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;___________________________________________________________________________________________________________________&lt;br /&gt;&lt;i&gt;Page Created&lt;a href="http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=WikiGuidelines&amp;amp;referringTitle=Home"&gt; &lt;/a&gt;By: Arnie Rowland, Mar 12, 2008&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>SuprotimAgarwal</author><pubDate>Thu, 26 Jun 2008 08:59:37 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20080626A</guid></item><item><title>UPDATED WIKI: RecursiveCTE</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=RecursiveCTE&amp;version=9</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
Exploring Recursive Common Table Expressions (CTE)
&lt;/h1&gt; &lt;br /&gt;A Common Table Expression(CTE) is an ANSI SQL-99 temporary result set that can be declared once and referenced multiple times in a query. It acts as a replacement for many sub-queries and thereby improves query simplicity and performance in most cases.&lt;br /&gt; &lt;br /&gt;If you are new to CTE's, I would recommend you to check this link &lt;a href="http://msdn.microsoft.com/en-us/library/ms190766.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms190766.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;  before you proceed ahead with Recursive CTE's.&lt;br /&gt; &lt;br /&gt;A recursive CTE is one in which a CTE refers to itself in the CTE definition to obtain subsets of data until the complete result set is obtained. Recursive CTE's come in quiet handy when you need to represent hierarchical data and query against it. Infact,  the raw power of a CTE is realized when it is used recursively to obtain a resultset. In previous versions of SQL Server, you could create recursive queries using cursors and temporary tables.&lt;br /&gt; &lt;br /&gt;The syntax of a recursive query would be similar to the following:&lt;br /&gt; &lt;br /&gt;WITH cte-nm (&lt;i&gt;column&lt;/i&gt;1, column&lt;i&gt;2, ...&lt;/i&gt;)  &lt;br /&gt;AS  &lt;br /&gt;( &lt;br /&gt;cte-query-definition   -- Anchor member&lt;br /&gt;UNION ALL &lt;br /&gt;cte-query-definition –- Recursive member which references cte_name&lt;br /&gt;)  &lt;br /&gt;SELECT * FROM cte-nm  &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;In this sample, we will see how to use Recursive CTE's to find out the level of a team member in a project.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Case Scenario&lt;/b&gt; : Let us assume that we have a table called ProjectMemberDetails. We need to display the 'Level' of each TeamMember in that project. The level of each team member will be ascertained by the hierarchy of Managers above the person.&lt;br /&gt; &lt;br /&gt;For the sake of demonstrating Recursive CTE's, we will create the following columns in the ProjectMemberDetails table - ID, TeamMemNm, Designation and ManagerID. Using Recursive CTE's, we will then calculate the level of each team member in the team. Level 1 is the highest grade, given only to those who do not have managers above them; in our case the EngagementManager.&lt;br /&gt; &lt;br /&gt;The hierarchy of a project team for demonstratation purposes is as follows:&lt;br /&gt; &lt;br /&gt;EngagementManager - 1&lt;br /&gt;Sr. Project Manager - 2&lt;br /&gt;Project Manager - 3&lt;br /&gt;Project Leader - 4&lt;br /&gt;Team Leader - 5&lt;br /&gt;Sr. Developer - 6&lt;br /&gt;Developer/Tester - 7&lt;br /&gt; &lt;br /&gt;The code to display the hierarchy would be as follows:&lt;br /&gt; &lt;br /&gt;&lt;b&gt;SQL Server 2005/SQL Server 2008&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;
DROP TABLE #ProjectMemberDetails
-- create temporary table called ProjectMemberDetails
CREATE TABLE #ProjectMemberDetails
(
ID int Identity(1,1) PRIMARY KEY,
TeamMemNm varchar(100),
Designation varchar(50),
ManagerID int NULL
)
 
-- Insert some sample records in the ProjectMemberDetails table
INSERT INTO #ProjectMemberDetails VALUES('Tim','Engagement Manager',NULL);
INSERT INTO #ProjectMemberDetails VALUES('Kathy','Sr. Project Manager',1);
INSERT INTO #ProjectMemberDetails VALUES('Levonca','Project Manager',2);
INSERT INTO #ProjectMemberDetails VALUES('Sid','Project Manager',2);
INSERT INTO #ProjectMemberDetails VALUES('Carrie','Project Leader',3);
INSERT INTO #ProjectMemberDetails VALUES('Cristina','Project Leader',4);
INSERT INTO #ProjectMemberDetails VALUES('Santi','Team Leader',5);
INSERT INTO #ProjectMemberDetails VALUES('Michelle','Team Leader',5);
INSERT INTO #ProjectMemberDetails VALUES('Pablo','Team Leader',6);
INSERT INTO #ProjectMemberDetails VALUES('Mario','Team Leader',6);
INSERT INTO #ProjectMemberDetails VALUES('Anand','Sr. Developer',7);
INSERT INTO #ProjectMemberDetails VALUES('Bill','Sr. Developer',7);
INSERT INTO #ProjectMemberDetails VALUES('Jack','Sr. Developer',8);
INSERT INTO #ProjectMemberDetails VALUES('Tibre','Sr. Developer',8);
INSERT INTO #ProjectMemberDetails VALUES('Lisa','Sr. Developer',9);
INSERT INTO #ProjectMemberDetails VALUES('Scott','Sr. Tester',10);
INSERT INTO #ProjectMemberDetails VALUES('Nancy','Developer',11);
INSERT INTO #ProjectMemberDetails VALUES('MJ','Developer',12);
INSERT INTO #ProjectMemberDetails VALUES('Ziak','Developer',13);
INSERT INTO #ProjectMemberDetails VALUES('Martin','Developer',14);
INSERT INTO #ProjectMemberDetails VALUES('David','Developer',14);
INSERT INTO #ProjectMemberDetails VALUES('Steve','Developer',15);
INSERT INTO #ProjectMemberDetails VALUES('Rachael','Developer',15);
INSERT INTO #ProjectMemberDetails VALUES('Sally','Tester',16);
INSERT INTO #ProjectMemberDetails VALUES('Peter','Tester',16);
SELECT * FROM #ProjectMemberDetails;
 
-- Use Recursive CTE to find out the Level of each ProjectMemberDetails
-- in the project
WITH CTE(ID, TeamMemberName, Designation, ManagerID, ProjectLevel)
AS
(
SELECT ID, TeamMemNm, Designation, ManagerID, 1 as ProjectLevel
From #ProjectMemberDetails WHERE ManagerID is NULL
UNION ALL
SELECT e.ID, e.TeamMemNm, e.Designation, e.ManagerID, c.ProjectLevel + 1
FROM #ProjectMemberDetails e
INNER JOIN CTE c
ON e.ManagerID = c.ID
)
SELECT ID, TeamMemberName, Designation, ManagerID, ProjectLevel
FROM CTE Order BY ID
 
 
&lt;/pre&gt; &lt;br /&gt;Here's a break up of the query:&lt;br /&gt; &lt;br /&gt;1. In the query below, the anchor member returns the person who is at the highest level in the project (Engagement Manager) and marks the level as 1&lt;br /&gt; &lt;br /&gt;SELECT ID, TeamMemNm, Designation, ManagerID, 1 as ProjectLevel&lt;br /&gt;From #ProjectMemberDetails WHERE ManagerID is NULL&lt;br /&gt; &lt;br /&gt;2.  To determine the person directly below him (EngagementManager), a join is made between the ProjectMemberDetails table and the CTE, which helps in determining the member which is directly below the person returned by the anchor member. In our case, that would be the Project Manager.  &lt;br /&gt; &lt;br /&gt;3. With every recursive invocation, we get the output (c.ProjectLevel + 1) for the join e.ManagerID = c.ID&lt;br /&gt; &lt;br /&gt;The final result set consists of the union of all the subsets generated by the anchor and recursive members. The result set is displayed below.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Result&lt;/b&gt;&lt;br /&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;&lt;th&gt;TeamMemberName&lt;/th&gt;&lt;th&gt;Designation&lt;/th&gt;&lt;th&gt;ManagerID&lt;/th&gt;&lt;th&gt;ProjectLevel&lt;/th&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;&lt;td&gt;	Tim&lt;/td&gt;&lt;td&gt;	Engagement Manager&lt;/td&gt;&lt;td&gt; NULL&lt;/td&gt;&lt;td&gt;	1&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;&lt;td&gt;	Kathy&lt;/td&gt;&lt;td&gt;        Sr. Project Manager	&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;	2&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;&lt;td&gt;	Levonca&lt;/td&gt;&lt;td&gt;	Project Manager&lt;/td&gt;&lt;td&gt;	2&lt;/td&gt;&lt;td&gt;	3&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;&lt;td&gt;	Sid&lt;/td&gt;&lt;td&gt;	Project Manager&lt;/td&gt;&lt;td&gt;	2&lt;/td&gt;&lt;td&gt;	3&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;&lt;td&gt;	Carrie&lt;/td&gt;&lt;td&gt;	Project Leader&lt;/td&gt;&lt;td&gt;	3&lt;/td&gt;&lt;td&gt;	4&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;&lt;td&gt;	Cristina&lt;/td&gt;&lt;td&gt;	Project Leader&lt;/td&gt;&lt;td&gt;	4&lt;/td&gt;&lt;td&gt;	4&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;&lt;td&gt;	Santi	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;&lt;td&gt;	Michelle	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;&lt;td&gt;	Pablo	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;&lt;td&gt;	Mario	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;&lt;td&gt;	Anand	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;&lt;td&gt;	Bill	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;&lt;td&gt;	Jack	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	8&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;&lt;td&gt;	Tibre	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	8&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;&lt;td&gt;	Lisa	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	9&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;&lt;td&gt;	Scott	&lt;/td&gt;&lt;td&gt;Sr. Tester&lt;/td&gt;&lt;td&gt;               10&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;17&lt;/td&gt;&lt;td&gt;	Nancy	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	11&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;&lt;td&gt;	MJ	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	12&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;&lt;td&gt;	Ziak	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	13&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;&lt;td&gt;	Martin	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	14&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;&lt;td&gt;	David	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	14&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;22&lt;/td&gt;&lt;td&gt;	Steve	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	15&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;23&lt;/td&gt;&lt;td&gt;	Rachael	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	15&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;&lt;td&gt;	Sally	&lt;/td&gt;&lt;td&gt;Tester&lt;/td&gt;&lt;td&gt;	                16&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;25&lt;/td&gt;&lt;td&gt;	Peter	&lt;/td&gt;&lt;td&gt;Tester&lt;/td&gt;&lt;td&gt;	                 16&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt; &lt;br /&gt;References: &lt;a href="http://msdn.microsoft.com/en-us/library/ms186243.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms186243.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>SuprotimAgarwal</author><pubDate>Thu, 26 Jun 2008 08:57:17 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: RecursiveCTE 20080626A</guid></item><item><title>UPDATED WIKI: RecursiveCTE</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=RecursiveCTE&amp;version=8</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
Exploring Recursive Common Table Expressions (CTE)
&lt;/h1&gt; &lt;br /&gt;A Common Table Expression(CTE) is an ANSI SQL-99 temporary result set that can be declared once and referenced multiple times in a query. It acts as a replacement for many sub-queries and thereby improves query simplicity and performance in most cases.&lt;br /&gt; &lt;br /&gt;If you are new to CTE's, I would recommend you to check this link &lt;a href="http://msdn.microsoft.com/en-us/library/ms190766.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms190766.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;  before you proceed ahead with Recursive CTE's.&lt;br /&gt; &lt;br /&gt;A recursive CTE is one in which a CTE refers to itself in the CTE definition to obtain subsets of data until the complete result set is obtained. Recursive CTE's come in quiet handy when you need to represent hierarchical data and query against it. Infact,  the raw power of a CTE is realized when it is used recursively to obtain a resultset. In previous versions of SQL Server, you could create recursive queries using cursors and temporary tables.&lt;br /&gt; &lt;br /&gt;The syntax of a recursive query would be similar to the following:&lt;br /&gt; &lt;br /&gt;WITH cte-nm (&lt;i&gt;column&lt;/i&gt;1, column&lt;i&gt;2, ...&lt;/i&gt;)  &lt;br /&gt;AS  &lt;br /&gt;( &lt;br /&gt;cte-query-definition   -- Anchor member&lt;br /&gt;UNION ALL &lt;br /&gt;cte-query-definition –- Recursive member which references cte_name&lt;br /&gt;)  &lt;br /&gt;SELECT * FROM cte-nm  &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;In this sample, we will see how to use Recursive CTE's to find out the level of a team member in a project.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Case Scenario&lt;/b&gt; : Let us assume that we have a table called ProjectMemberDetails. We need to display the 'Level' of each TeamMember in that project. The level of each team member will be ascertained by the hierarchy of Managers above the person.&lt;br /&gt; &lt;br /&gt;For the sake of demonstrating Recursive CTE's, we will create the following columns in the ProjectMemberDetails table - ID, TeamMemNm, Designation and ManagerID. Using Recursive CTE's, we will then calculate the level of each team member in the team. Level 1 is the highest grade, given only to those who do not have managers above them; in our case the EngagementManager.&lt;br /&gt; &lt;br /&gt;The hierarchy of a project team for demonstratation purposes is as follows:&lt;br /&gt; &lt;br /&gt;EngagementManager - 1&lt;br /&gt;Sr. Project Manager - 2&lt;br /&gt;Project Manager - 3&lt;br /&gt;Project Leader - 4&lt;br /&gt;Team Leader - 5&lt;br /&gt;Sr. Developer - 6&lt;br /&gt;Developer/Tester - 7&lt;br /&gt; &lt;br /&gt;The code to display the hierarchy would be as follows:&lt;br /&gt; &lt;br /&gt;&lt;b&gt;SQL Server 2005/SQL Server 2008&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;
DROP TABLE #ProjectMemberDetails
-- create temporary table called ProjectMemberDetails
CREATE TABLE #ProjectMemberDetails
(
ID int Identity(1,1) PRIMARY KEY,
TeamMemNm varchar(100),
Designation varchar(50),
ManagerID int NULL
)
 
-- Insert some sample records in the ProjectMemberDetails table
INSERT INTO #ProjectMemberDetails VALUES('Tim','Engagement Manager',NULL);
INSERT INTO #ProjectMemberDetails VALUES('Kathy','Sr. Project Manager',1);
INSERT INTO #ProjectMemberDetails VALUES('Levonca','Project Manager',2);
INSERT INTO #ProjectMemberDetails VALUES('Sid','Project Manager',2);
INSERT INTO #ProjectMemberDetails VALUES('Carrie','Project Leader',3);
INSERT INTO #ProjectMemberDetails VALUES('Cristina','Project Leader',4);
INSERT INTO #ProjectMemberDetails VALUES('Santi','Team Leader',5);
INSERT INTO #ProjectMemberDetails VALUES('Michelle','Team Leader',5);
INSERT INTO #ProjectMemberDetails VALUES('Pablo','Team Leader',6);
INSERT INTO #ProjectMemberDetails VALUES('Mario','Team Leader',6);
INSERT INTO #ProjectMemberDetails VALUES('Anand','Sr. Developer',7);
INSERT INTO #ProjectMemberDetails VALUES('Bill','Sr. Developer',7);
INSERT INTO #ProjectMemberDetails VALUES('Jack','Sr. Developer',8);
INSERT INTO #ProjectMemberDetails VALUES('Tibre','Sr. Developer',8);
INSERT INTO #ProjectMemberDetails VALUES('Lisa','Sr. Developer',9);
INSERT INTO #ProjectMemberDetails VALUES('Scott','Sr. Tester',10);
INSERT INTO #ProjectMemberDetails VALUES('Nancy','Developer',11);
INSERT INTO #ProjectMemberDetails VALUES('MJ','Developer',12);
INSERT INTO #ProjectMemberDetails VALUES('Ziak','Developer',13);
INSERT INTO #ProjectMemberDetails VALUES('Martin','Developer',14);
INSERT INTO #ProjectMemberDetails VALUES('David','Developer',14);
INSERT INTO #ProjectMemberDetails VALUES('Steve','Developer',15);
INSERT INTO #ProjectMemberDetails VALUES('Rachael','Developer',15);
INSERT INTO #ProjectMemberDetails VALUES('Sally','Tester',16);
INSERT INTO #ProjectMemberDetails VALUES('Peter','Tester',16);
SELECT * FROM #ProjectMemberDetails;
 
-- Use Recursive CTE to find out the Level of each ProjectMemberDetails
-- in the project
WITH CTE(ID, TeamMemberName, Designation, ManagerID, ProjectLevel)
AS
(
SELECT ID, TeamMemNm, Designation, ManagerID, 1 as ProjectLevel
From #ProjectMemberDetails WHERE ManagerID is NULL
UNION ALL
SELECT e.ID, e.TeamMemNm, e.Designation, e.ManagerID, c.ProjectLevel + 1
FROM #ProjectMemberDetails e
INNER JOIN CTE c
ON e.ManagerID = c.ID
)
SELECT ID, TeamMemberName, Designation, ManagerID, ProjectLevel
FROM CTE Order BY ID
 
 
&lt;/pre&gt; &lt;br /&gt;Here's a break up of the query:&lt;br /&gt; &lt;br /&gt;1. In the query below, the anchor member returns the person who is at the highest level in the project (Engagement Manager) and marks the level as 1&lt;br /&gt; &lt;br /&gt;SELECT ID, TeamMemNm, Designation, ManagerID, 1 as ProjectLevel&lt;br /&gt;From #ProjectMemberDetails WHERE ManagerID is NULL&lt;br /&gt; &lt;br /&gt;2.  To determine the person directly below him (EngagementManager), a join is made between the ProjectMember table and the CTE, which helps in determining the member which is directly below the person returned by the anchor member. In our case, that would be the Project Manager.  &lt;br /&gt; &lt;br /&gt;3. With every recursive invocation, we get the output (c.ProjectLevel + 1) for the join e.ManagerID = c.ID&lt;br /&gt; &lt;br /&gt;The final result set consists of the union of all the subsets generated by the anchor and recursive members. The result set is displayed below.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Result&lt;/b&gt;&lt;br /&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;&lt;th&gt;TeamMemberName&lt;/th&gt;&lt;th&gt;Designation&lt;/th&gt;&lt;th&gt;ManagerID&lt;/th&gt;&lt;th&gt;ProjectLevel&lt;/th&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;&lt;td&gt;	Tim&lt;/td&gt;&lt;td&gt;	Engagement Manager&lt;/td&gt;&lt;td&gt; NULL&lt;/td&gt;&lt;td&gt;	1&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;&lt;td&gt;	Kathy&lt;/td&gt;&lt;td&gt;        Sr. Project Manager	&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;	2&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;&lt;td&gt;	Levonca&lt;/td&gt;&lt;td&gt;	Project Manager&lt;/td&gt;&lt;td&gt;	2&lt;/td&gt;&lt;td&gt;	3&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;&lt;td&gt;	Sid&lt;/td&gt;&lt;td&gt;	Project Manager&lt;/td&gt;&lt;td&gt;	2&lt;/td&gt;&lt;td&gt;	3&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;&lt;td&gt;	Carrie&lt;/td&gt;&lt;td&gt;	Project Leader&lt;/td&gt;&lt;td&gt;	3&lt;/td&gt;&lt;td&gt;	4&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;&lt;td&gt;	Cristina&lt;/td&gt;&lt;td&gt;	Project Leader&lt;/td&gt;&lt;td&gt;	4&lt;/td&gt;&lt;td&gt;	4&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;&lt;td&gt;	Santi	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;&lt;td&gt;	Michelle	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;&lt;td&gt;	Pablo	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;&lt;td&gt;	Mario	&lt;/td&gt;&lt;td&gt;Team Leader&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;&lt;td&gt;	5&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;&lt;td&gt;	Anand	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;&lt;td&gt;	Bill	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;&lt;td&gt;	Jack	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	8&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;&lt;td&gt;	Tibre	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	8&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;&lt;td&gt;	Lisa	&lt;/td&gt;&lt;td&gt;Sr. Developer&lt;/td&gt;&lt;td&gt;	9&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;&lt;td&gt;	Scott	&lt;/td&gt;&lt;td&gt;Sr. Tester&lt;/td&gt;&lt;td&gt;               10&lt;/td&gt;&lt;td&gt;	6&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;17&lt;/td&gt;&lt;td&gt;	Nancy	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	11&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;&lt;td&gt;	MJ	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	12&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;&lt;td&gt;	Ziak	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	13&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;&lt;td&gt;	Martin	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	14&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;&lt;td&gt;	David	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	14&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;22&lt;/td&gt;&lt;td&gt;	Steve	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	15&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;23&lt;/td&gt;&lt;td&gt;	Rachael	&lt;/td&gt;&lt;td&gt;Developer&lt;/td&gt;&lt;td&gt;	15&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;&lt;td&gt;	Sally	&lt;/td&gt;&lt;td&gt;Tester&lt;/td&gt;&lt;td&gt;	                16&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;
&lt;td&gt;25&lt;/td&gt;&lt;td&gt;	Peter	&lt;/td&gt;&lt;td&gt;Tester&lt;/td&gt;&lt;td&gt;	                 16&lt;/td&gt;&lt;td&gt;	7&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt; &lt;br /&gt;References: &lt;a href="http://msdn.microsoft.com/en-us/library/ms186243.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms186243.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>SuprotimAgarwal</author><pubDate>Thu, 26 Jun 2008 08:55:46 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: RecursiveCTE 20080626A</guid></item><item><title>UPDATED WIKI: RecursiveCTE</title><link>http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=RecursiveCTE&amp;version=7</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;
Exploring Recursive Common Table Expressions (CTE)
&lt;/h1&gt; &lt;br /&gt;A Common Table Expression(CTE) is an ANSI SQL-99 temporary result set that can be declared once and referenced multiple times in a query. It acts as a replacement for many sub-queries and thereby improves query simplicity and performance in most cases.&lt;br /&gt; &lt;br /&gt;If you are new to CTE's, I would recommend you to check this link &lt;a href="http://msdn.microsoft.com/en-us/library/ms190766.aspx" class="externalLink"&gt;http://msdn.microsoft.com/en-us/library/ms190766.aspx&lt;span class="externalLinkIcon"&gt;&lt;/span&gt;&lt;/a&gt;  before you proceed ahead with Recursive CTE's.&lt;br /&gt; &lt;br /&gt;Recursive CTE's come in quiet handy when you need to represent hierarchical data and query against it. Infact,  the raw power of a CTE is realized when it is used recursively to obtain a resultset. In previous versions of SQL Server, you could create recursive queries using cursors and temporary tables.&lt;br /&gt; &lt;br /&gt;A recursive CTE is one in which a CTE refers to itself in the CTE definition to obtain subsets of data until the complete result set is obtained.&lt;br /&gt; &lt;br /&gt;The syntax of a recursive query would be similar to the following:&lt;br /&gt; &lt;br /&gt;WITH cte-nm (&lt;i&gt;column&lt;/i&gt;1, column&lt;i&gt;2, ...&lt;/i&gt;)  &lt;br /&gt;AS  &lt;br /&gt;( &lt;br /&gt;cte-query-definition   -- Anchor member&lt;br /&gt;UNION ALL &lt;br /&gt;cte-query-definition –- Recursive member which references cte_name&lt;br /&gt;)  &lt;br /&gt;SELECT * FROM cte-nm  &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;In this sample, we will see how to use Recursive CTE's to find out the level of a team member in a project.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Case Scenario&lt;/b&gt; : Let us assume that we have a table called ProjectMemberDetails. We need to display the 'Level' of each TeamMember in that project. The level of each team member will be ascertained by the hierarchy of Managers above the person.&lt;br /&gt; &lt;br /&gt;For the sake of demonstrating Recursive CTE's, we will create the following columns in the ProjectMemberDetails table - ID, TeamMemNm, Designation and ManagerID. Using Recursive CTE's, we will then calculate the level of each team member in the team. Level 1 is the highest grade, given only to those who do not have managers above them; in our case the EngagementManager.&lt;br /&gt; &lt;br /&gt;The hierarchy of a project team for demonstratation purposes is as follows:&lt;br /&gt; &lt;br /&gt;EngagementManager - 1&lt;br /&gt;Sr. Project Manager - 2&lt;br /&gt;Project Manager - 3&lt;br /&gt;Project Leader - 4&lt;br /&gt;Team Leader - 5&lt;br /&gt;Sr. Developer - 6&lt;br /&gt;Developer/Tester - 7&lt;br /&gt; &lt;br /&gt;The code to display the hierarchy would be as follows:&lt;br /&gt; &lt;br /&gt;&lt;b&gt;SQL Server 2005/SQL Server 2008&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;
DROP TABLE #ProjectMemberDetails
-- create temporary table called ProjectMemberDetails
CREATE TABLE #ProjectMemberDetails
(
ID int Identity(1,1) PRIMARY KEY,
TeamMemNm varchar(100),
Designation varchar(50),
ManagerID int NULL
)
 
-- Insert some sample records in the ProjectMemberDetails table
INSERT INTO #ProjectMemberDetails VALUES('Tim','Engagement Manager',NULL);
INSERT INTO #ProjectMemberDetails VALUES('Kathy','Sr. Project Manager',1);
INSERT INTO #ProjectMemberDetails VALUES('Levonca','Project Manager',2);
INSERT INTO #ProjectMemberDetails VALUES('Sid','Project Manager',2);
INSERT INTO #ProjectMemberDetails VALUES('Carrie','Project Leader',3);
INSERT INTO #ProjectMemberDetails VALUES('Cristina','Project Leader',4);
INSERT INTO #ProjectMemberDetails VALUES('Santi','Team Leader',5);
INSERT INTO #ProjectMemberDetails VALUES('Michelle','Team Leader',5);
INSERT INTO #ProjectMemberDetails VALUES('Pablo','Team Leader',6);
INSERT INTO #ProjectMemberDetails VALUES('Mario','Team Leader',6);
INSERT INTO #ProjectMemberDetails VALUES('Anand','Sr. Developer',7);
INSERT INTO #ProjectMemberDetails VALUES('Bill','Sr. Developer',7);
INSERT INTO #ProjectMemberDetails VALUES('Jack','Sr. Developer',8);
INSERT INTO #ProjectMemberDetails VALUES('Tibre','Sr. Developer',8);
INSERT INTO #ProjectMemberDetails VALUES('Lisa','Sr. Developer',9);
INSERT INTO #ProjectMemberDetails VALUES('Scott','Sr. Tester',10);
INSERT INTO #ProjectMemberDetails VALUES('Nancy','Developer',11);
INSERT INTO #ProjectMemberDetails VALUES('MJ','Developer',12);
INSERT INTO #ProjectMemberDetails VALUES('Ziak','Developer',13);
INSERT INTO #ProjectMemberDetails VALUES('Martin','Developer',14);
INSERT INTO #ProjectMemberDetails VALUES('David','Developer',14);
INSERT INTO #ProjectMemberDetails VALUES('Steve','Developer',15);
INSERT INTO #ProjectMemberDetails VALUES('Rachael','Developer',15);
INSERT INTO #ProjectMemberDetails VALUES('Sally','Tester',16);
INSERT INTO #ProjectMemberDetails VALUES('Peter','Tester',16);
SELECT * FROM #ProjectMemberDetails;
 
-- Use Recursive CTE to find out the Level of each ProjectMemberDetails
-- in the project
WITH CTE(ID, TeamMemberName, Designation, ManagerID, ProjectLevel)
AS
(
SELECT ID, TeamMemNm, Designation, ManagerID, 1 as ProjectLevel
From #ProjectMemberDetails WHERE ManagerID is NULL
UNION ALL
SELECT e.ID, e.TeamMemNm, e.Designation, e.ManagerID, c.ProjectLevel + 