How to Use Row_Number in SQL Server

This function is extremely useful. As of late, I use it mainly to help me manage a loop within a loop, which we will save for another time because I need to release said recent work to other users who are not me. However, I want to document this information somewhere for quick and easy reference of my own.

Here is a scenario. I want to create a temporary table of records, and I need to iterate through each row, and I need to a do it in a specific order. I need the row number to act like a record number for just this temporary table, like so:

Declare @tblExample table (idRecord int, idLocation int, dtDate datetime)

Insert into @tblExample

Select Row_Number() Over (order by dtDate) as idRecord, idLocation, dtDate
From tblTask a
	join tblLocation b
		on a.idLocation = b.idLocation
Where 1 = 1
and dtDate >= getdate()

Sometimes I end up removing items from a temporary table and need to reset the idRecord column so that it updates to new row numbers. I can do that with the following code:

Here is how to do that:

Update a
Set idRecord = a.idRecordNew
From
	(
		Select Row_Number() Over (Order by idRecord, idLocation, dtDate) as idRecordNew
		From @tblExample
	) a

That is all for this post.

Creating a Table to Hold Dates for a Year in SQL Server and Maintaining That Table

The scenario:
We want a table that is a list of dates. We really only need the dates between today and one year from today at most, not much more and not much less.

So first, we are going take the current date (@CurrentDate), calculate up to the date we want (one year from today plus one more day so that our table will start at 5/16/2018 and end at 5/16/2019, naming it @YearLaterDate). Because of leap years, the difference might be 367 instead of 366, so we are going to make a variable (@DaysDiff) to help us know that. Once we have that difference, we can loop through up to that number and then insert into our example table.

Declare @CurrentDate date
Declare @YearLaterDate date
Declare @DaysDiff int
Declare @DayCounter int
Create Table tblDateExample (dtDate date)
Set @CurrentDate = getdate()
Set @YearLaterDate = DateAdd(year,1,@CurrentDate)
Set @YearLaterDate = DateAdd(day,1,@YearLaterDate)
Set @DaysDiff = DateDiff(day,@CurrentDate,@YearLaterDate)
Set @Daycounter = 0

while @DayCounter < @DaysDiff
begin
	Insert into tblDateExample
	(dtDate)
	VALUES
	(DateAdd(day,@DayCounter,@CurrentDate))
	Set @DayCounter = @DayCounter + 1
end

Select *
From tblDateExample
Where 1 = 1

Hurray! We've made our table! But wait. Once tomorrow comes along, we will not need 5/16/2018 anymore and will want to add in 5/17/2018. Use whatever means you have for a scheduled task and run the following query once a day. We are going to use many similar variables because we have similar uses. We know we want the table for, from today, to a year from today plus one more day, so use those same ones again. Instead of the difference between those though, we are going to get the maximum date in our example table. Why? To handle for mishaps where we might need to add two days, or thirty days, instead of one. So, now we get the difference between our current maximum and our desired maximum, loop through that difference instead and add any days accordingly. We'll make a quick delete of anything before the day before the current date as well and anything after in case extra dates were added somehow.

Our maintaining query:

Declare @CurrentDate date
Declare @YearLaterDate date
Declare @DayCounter int
Declare @CurrentMax date
Declare @MaxDiff int	
Set @CurrentDate = getdate()
Set @YearLaterDate = DateAdd(year,1,@CurrentDate)
Set @YearLaterDate = DateAdd(day,1,@YearLaterDate)
Set @DayCounter = 0
Set @CurrentMax = (select max(dtDate) from tblDateExample)
Set @MaxDiff = DateDiff(day,@CurrentMax,@YearLaterDate)	
	
delete from tblDateExample where dtDate < @CurrentDate;
delete from tblDateExample where dtDate > @YearLaterDate;

while @DayCounter < @MaxDiff
begin
	Update  tblDateExample
	Set dtDate = dtDate
	Where dtDate = DateAdd(day,@DayCounter,@CurrentMax)
		
	if @@rowcount = 0
	begin
	Insert into  tblDateExample
	(dtDate)
	VALUES
	(DateAdd(day,@DayCounter,@CurrentMax))	
	end
	Set @DayCounter = @DayCounter + 1
end

Now we have a table that keeps the dates for roughly up to a year from the current date to a year from that.

Using SQL to Determine the Sunday and Saturday of the Calendar Week Based on a Given Date

Recently at work, a manager asked that I show some records but restrict them based on the calendar Sunday through Saturday week of a given date.

I did my usual Google search for this particular request, which gave me some ideas though none really gave exactly what I wanted because for some reason, Sundays throw certain expected calculations off.

With that in mind, I decided to write some extra lines just to make it more clear to me what I was accomplishing to get the dates and figured it might be useful to other visitors to this blog.

So, here it is, this is written specifically for SQL Server 2008.

Declare @DateToCheck datetime
Declare @SubtractForSunday int
Declare @AddForSaturday int
Declare @SundayDate datetime
Declare @SaturdayDate datetime
Set @DateToCheck =  DATEADD(d, 0, DATEDIFF(d, 0, GETDATE()))
Set @SubtractForSunday = DATEPART(dw,@DateToCheck) - 1
Set @AddForSaturday = 7 - DATEPART(dw,@DateToCheck)
Set @SundayDate = DateAdd(day,-@SubtractForSunday,@DateToCheck)
Set @SaturdayDate = DateAdd(day,@AddForSaturday,@DateToCheck)	

Select idThing
From tblThing
Where 1 = 1
and dtSomeDate between @SundayDate and @SaturdayDate

To break it down a little so you know what I am doing:

The DATEADD(d, 0, DATEDIFF(d, 0, GETDATE())) portion is to set the current date/time to midnight. You can get around this by making the @DateToCheck variable a date variable, instead of datetime, or making sure the datetime variables you are working with already set to midnight, which was the case for my own particular situation. I’m showing the midnight here because that is not always the case and is useful for my own reference.

Sunday is always day 1 and Saturday is always day 7. Those are known quantities. Once we have a date to check, we can get that date’s day of the week number that is 1 through 7 using algebra. If the day we are checking is 1 (Sunday) and we are aiming to get to 1 (Sunday) , we will want to subtract nothing, 1 – 0 = 1. If the day is 2 (Monday), we will want to subtract only 1, so 2 – 1 = 1. If the day is Saturday we will want that number to be 6, 7 – 6 = 1. We are starting to see a pattern where y is the day of the week are checking and x is the number that will give us the necessary subtraction for reaching 1: yx = 1. We take that same logic to give us Saturday: v + w = 7. The @SubtractForSunday variable is determined by re-working this equation to look like x = y – 1 and the @AddForSaturday variable is determined by re-working it to w = 7 – v.

Because once we have that number, we can proceed to the original form of the equation and use the DateAdd function, making sure to have our minus sign in front of our @SubtractForSunday variable.

If you wanted to condense it instead of lay out all like that, you could do:

Set @SundayDate = DateAdd(day,-(DATEPART(dw,@DateToCheck) - 1),@DateToCheck)
Set @SaturdayDate = DateAdd(day,(7 - DATEPART(dw,@DateToCheck)),@DateToCheck)	

If you appreciate any of the work that went into making this post, please consider giving a tip to my PayPal account:
https://www.paypal.me/sonkitty