Solved

TSQL help request - More efficient loop code than this?

Posted on 2009-06-30
7
161 Views
Last Modified: 2012-05-07
I have a 'map' in SQL which currently consists of a grid of 100x100 'squares'.
This is for a web-based game I'm toying with making.
The final one would need many more squares, more like 10k x 10k.

My problem is the way I've written the code, it uses a very basic loop, incrementing a number each time through, raising the 'key' by 1 each time.
I do it this way because I want each square to have a random temperature based on that particular squares average temperature.

Is there a more efficient way of coding this so it doesn't have to loop through it 10,000 times? Some way of implementing it so it can update all records at once?
I'm in the process of learning SQL as I go, so really don't know what's possible. Maybe I'm trying to do the impossible here..?

Any help or advice appreciated.
declare @TempAv int
declare @TempVar int
declare @temp int
declare @rain int
 
While @count <= (Select top 1 [num] from Map order by [num] desc)
BEGIN
	--Get Variables for this area
	set @TempAv = (Select [TempAv] from [map] where [num]=@count)
	set @TempVar = (Select [TempVar] from [map] where [num]=@count)
 
	--Set Temperature
	If @Season = '0'
		set @temp = @TempAv + convert(int, 0 + @TempVar * RAND(CHECKSUM(NEWID()))) - (@TempVar / 2)
	Else if @Season = '1'
		set @temp = @TempAv + convert(int, 0 + @TempVar * RAND(CHECKSUM(NEWID()))) + (@TempVar / 2)
	Else if @Season = '2'
		set @temp = @TempAv + convert(int, 0 + @TempVar * RAND(CHECKSUM(NEWID()))) - (@TempVar / 2)
	Else if @Season = '3'
		set @temp = @TempAv - convert(int, 0 + @TempVar * RAND(CHECKSUM(NEWID()))) - (@TempVar / 2)
 
	update Map
	Set [TempNow] = @temp where [num] = @count
END

Open in new window

0
Comment
Question by:CreepyD
7 Comments
 
LVL 59

Expert Comment

by:Kevin Cross
ID: 24748799
Try something like this.
+Only variation I saw in the formula was if season was '3', you subtract the latter portion of formula versus add.
+TempAv and TempVar appear to come from same row, so should not need to store in variables first.
update Map
Set [TempNow] = TempAv + CASE @Season WHEN '3' THEN -1 ELSE 1 END * CAST(0 + @TempVar * RAND(CHECKSUM(NEWID()))) - TempVar / 2 AS INT);

Open in new window

0
 
LVL 3

Expert Comment

by:BrightApollo
ID: 24748836
Do you realize you are performing the same set operation no matter what the value of @Season is?  Also, a table definition would be really helpful here.

I don't see any reason why you could write this, given what you have:

UPDATE Map
SET [TempNow] = ([TempAv] - CONVERT(INT, 0 + [TempVar] * RAND(CHECKSUM(NEWID()))) - ([TempVar] / 2))

No loops needed.

Now your problem is going to be computing all of those random numbers for all rows.  We'll get to that later.  See if this works for you.

--#


0
 
LVL 59

Accepted Solution

by:
Kevin Cross earned 400 total points
ID: 24748839
Alright, just saw additional difference and a type-o.  Try this:
update Map
Set [TempNow] = TempAv 
	+ CASE @Season 
		WHEN '3' THEN -1 
		ELSE 1 
	END * CAST(0 + @TempVar * RAND(CHECKSUM(NEWID())) AS INT) 
	- CASE @Season 
		WHEN '1' THEN -1 
		ELSE 1 
	END * (TempVar / 2);

Open in new window

0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 59

Expert Comment

by:Kevin Cross
ID: 24748854
Missed one last thing which was @TempVar should be just TempVar.  I see BrightApollo saw the same thing I did that you don't need the loop at all. ;)

Hope that helps.

Best regards,
Kevin
0
 
LVL 2

Assisted Solution

by:nikege
nikege earned 100 total points
ID: 24748997
Try something like this:

update [Map] 
set [TempNow] = case @Season when '0' then TempAv  + convert(int, 0 + TempVar * RAND(CHECKSUM(NEWID()))) - (TempVar / 2)
							when '1' then TempAv + convert(int, 0 +  TempVar * RAND(CHECKSUM(NEWID()))) + ( TempVar / 2)
							when '2' then  TempAv + convert(int, 0 +  TempVar * RAND(CHECKSUM(NEWID()))) - ( TempVar / 2)
							when '3' then  TempAv - convert(int, 0 +  TempVar * RAND(CHECKSUM(NEWID()))) - ( TempVar / 2)
							else 0
				end

Open in new window

0
 

Author Closing Comment

by:CreepyD
ID: 31598498
Awesome, thanks a lot guys, I was thinking I'd hit dead end but you've got me over it.  I will use this method for my other sections too!
mwvisa1 your code worked perfectly so I gave you most of the points as you were first, however I ended up using nikege's code which works the same but I can read it easier so a few points for you too  :)
0
 
LVL 59

Expert Comment

by:Kevin Cross
ID: 24749354
Yes, I had same thought as nikege initially, but seeing the similarities in the formula I used the multiplication by -1 to switch signs via case statement to give you reduced code.  Does make it a little harder to read, but simpler to maintain once you understand as you won't have to change the main calc of @TempVar * RAND(CHECKSUM(NEWID())) or (TempVar / 2) in four different places whenever you change logic.  

Best of luck to you and thanks for the points.

Regards,
Kevin
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

As they say in love and is true in SQL: you can sum some Data some of the time, but you can't always aggregate all Data all the time! Introduction: By the end of this Article it is my intention to bring the meaning and value of the above quote to…
'Between' is such a common word we rarely think about it but in SQL it has a very specific definition we should be aware of. While most database vendors will have their own unique phrases to describe it (see references at end) the concept in common …
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question