<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'SQL' and 'SQL Server'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=SQL,SQL+Server&amp;orTags=0</link><description>Search results matching tags 'SQL' and 'SQL Server'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>SQLSaturday #69 - Philly Love</title><link>http://sqlblog.com/blogs/michael_coles/archive/2011/03/06/sqlsaturday-69-philly-love.aspx</link><pubDate>Mon, 07 Mar 2011 01:38:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:33926</guid><dc:creator>Mike C</dc:creator><description>&lt;P&gt;Thanks to the Philly SQL Server User Group (PSSUG) and to everyone who attended SQLSaturday #69 in the City of Brotherly Love yesterday. It was a great event with a lot of great people.&amp;nbsp;My presentations are&amp;nbsp;available for&amp;nbsp;download at the links below:&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;A href="http://www.sqlsaturday.com/viewsession.aspx?sat=69&amp;amp;sessionid=3333"&gt;&lt;FONT size=3 face=Calibri&gt;http://www.sqlsaturday.com/viewsession.aspx?sat=69&amp;amp;sessionid=3333&lt;/FONT&gt;&lt;/A&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P style="MARGIN:0in 0in 10pt;" class=MsoNormal&gt;&lt;A href="http://www.sqlsaturday.com/viewsession.aspx?sat=69&amp;amp;sessionid=3334"&gt;&lt;FONT size=3 face=Calibri&gt;http://www.sqlsaturday.com/viewsession.aspx?sat=69&amp;amp;sessionid=3334&lt;/FONT&gt;&lt;/A&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P&gt;I just went through&amp;nbsp;my speaker evaluations, and I'm happy to report the response was pretty positive across the board. Having lived in Philly, I know Philadelphians aren't shy about telling how they really feel, so I really appreciate the positive feedback.&lt;/P&gt;
&lt;P&gt;For those of you who wrote comments with areas for improvement, rest assured I appreciate the feedback and I'll work your suggestions into future presentations!&lt;/P&gt;
&lt;P&gt;Next stop is SQLSaturday #71 in Boston (&lt;A href="http://www.sqlsaturday.com/71/eventhome.aspx"&gt;http://www.sqlsaturday.com/71/eventhome.aspx&lt;/A&gt;). Lots of top-notch speakers presenting at this one, and I'm looking forward to learning a little Power Shell from the master, and maybe learn a little bit o' that DBA stuff&amp;nbsp;this time around :)&lt;/P&gt;
&lt;P&gt;See you in Boston!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>Sell Yourself! Presentation</title><link>http://sqlblog.com/blogs/michael_coles/archive/2010/12/05/sell-yourself-presentation.aspx</link><pubDate>Sun, 05 Dec 2010 23:01:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:31374</guid><dc:creator>Mike C</dc:creator><description>&lt;P&gt;Thanks to everyone who attended my "Sell Yourself!" presentation at SQLSaturday #61 in Washington, D.C., and thanks to &lt;A title="NOVA SQL website" href="http://www.novasql.com/"&gt;NOVA SQL&lt;/A&gt;&amp;nbsp;for&amp;nbsp;setting up the event!&lt;/P&gt;
&lt;P&gt;I'm uploading the presentation deck here in PDF, original length, with new materials (I had to cut some slides out due to time limits).&amp;nbsp; This deck includes a new section on recruiters and a&amp;nbsp;little more information on the resume.&lt;/P&gt;
&lt;P&gt;BTW, if you're rewriting your resume I highly recommend the book Elements of Resume Style by S. Bennett.&amp;nbsp; I've used it as a reference when rewriting my resume and when helping others, and it's a very valuable tool.&amp;nbsp; There are one or two things I disagree with the author about (he recommends against the use of bulleted lists in the resume, I think they're great for emphasis and readability in certain areas so long as they're not overused, for instance); but overall the book has plenty of solid advice on how to get the most out of your resume.&lt;/P&gt;
&lt;P&gt;Also, if you haven't done so yet, check out Steve Jones' presentation "The Modern Resume: Building Your Brand" and his new blog: &lt;A href="http://modernresume.blogspot.com/"&gt;http://modernresume.blogspot.com/&lt;/A&gt;.&amp;nbsp; Steve is a SQL MVP, entrepreneur (a founder and editor-in-chief at SQL Server Central: &lt;A href="http://www.sqlservercentral.com/"&gt;http://www.sqlservercentral.com&lt;/A&gt;), SQL Server guru, and all-around great guy.&amp;nbsp; His new career-oriented professional-development blog and presentations are full of great career advice and tips for SQL Professionals.&lt;/P&gt;</description></item><item><title>Try-N-Save SSIS Packages</title><link>http://sqlblog.com/blogs/michael_coles/archive/2010/11/29/try-n-save-ssis-packages.aspx</link><pubDate>Mon, 29 Nov 2010 05:17:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:31096</guid><dc:creator>Mike C</dc:creator><description>&lt;P&gt;The Try-N-Save SSIS Packages from my SSIS Dimensional Data Optimization presentation are available at &lt;A href="http://cid-8f7e6c950afc6b3e.office.live.com/self.aspx/.Public/Presentation/TryNSave.zip"&gt;http://cid-8f7e6c950afc6b3e.office.live.com/self.aspx/.Public/Presentation/TryNSave.zip&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;I'm still working on getting the sample database uploaded - even compressed a backup is larger than SkyDrive's upload filesize limit. I'll script it out when I have time (in addition to DDL, there are some tables that need to be prepopulated).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>High Performance Dimensional Data Loads With SSIS Presentation</title><link>http://sqlblog.com/blogs/michael_coles/archive/2010/11/20/high-performance-dimensional-data-loads-with-ssis-presentation.aspx</link><pubDate>Sat, 20 Nov 2010 18:25:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:30834</guid><dc:creator>Mike C</dc:creator><description>&lt;P&gt;Just finished giving the SSIS High-Performance Dimensional Data Load presentation at &lt;A title="SQLSaturday #59 NYC" href="http://www.sqlsaturday.com/59/schedule.aspx"&gt;SQLSaturday #59 NYC&lt;/A&gt;.&amp;nbsp; Here are the slides in PDF format.&amp;nbsp; I'll upload the Try-N-Save&amp;nbsp;code and sample data later for attendees to play with.&lt;/P&gt;
&lt;P&gt;Thanks to everyone who attended my session and thanks to Melissa D. and NJSQL for putting this together.&amp;nbsp; For those who are interested in Alejandro Mesa's composable DML solution to the problem of Type 2 dimension updates, here's the complete statement from the demo:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;INSERT INTO Dim.Geography_Hash&lt;BR&gt;(&amp;nbsp;&lt;BR&gt;&amp;nbsp;CityName, CountyFIPS, CountyName, StateFIPS, &lt;BR&gt;&amp;nbsp;StateUSPS, StateName, ZIP, TimeOffset, &lt;BR&gt;&amp;nbsp;DaylightSavingTime, StartDateID, CurrentFlag, BatchID, &lt;BR&gt;&amp;nbsp;LineageID, CubeInd, SortOrder, Hash&lt;BR&gt;)&lt;BR&gt;SELECT CityName, CountyFIPS, CountyName, StateFIPS, &lt;BR&gt;&amp;nbsp;StateUSPS, StateName, ZIP, TimeOffset, &lt;BR&gt;&amp;nbsp;DaylightSavingTime, StartDateID, CurrentFlag, BatchID, &lt;BR&gt;&amp;nbsp;LineageID, CubeInd, SortOrder, Hash&lt;BR&gt;FROM&lt;BR&gt;(&lt;BR&gt;&amp;nbsp;MERGE INTO Dim.Geography_Hash AS Target&lt;BR&gt;&amp;nbsp;USING Staging.Geography_Hash AS Source&lt;BR&gt;&amp;nbsp;ON Target.ZIP = Source.ZIP&lt;BR&gt;&amp;nbsp;&amp;nbsp;AND Target.CurrentFlag = Source.CurrentFlag&lt;BR&gt;&amp;nbsp;WHEN MATCHED AND Target.Hash &amp;lt;&amp;gt; Source.Hash&lt;BR&gt;&amp;nbsp;&amp;nbsp;THEN UPDATE SET CurrentFlag = 'N'&lt;BR&gt;&amp;nbsp;WHEN NOT MATCHED&lt;BR&gt;&amp;nbsp;&amp;nbsp;THEN INSERT &lt;BR&gt;&amp;nbsp;&amp;nbsp;(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;CityName, CountyFIPS, CountyName, StateFIPS, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;StateUSPS, StateName, ZIP, TimeOffset, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;DaylightSavingTime, StartDateID, CurrentFlag, BatchID, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;LineageID, CubeInd, SortOrder, Hash&lt;BR&gt;&amp;nbsp;&amp;nbsp;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;VALUES&lt;BR&gt;&amp;nbsp;&amp;nbsp;(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Source.CityName, Source.CountyFIPS, Source.CountyName, Source.StateFIPS, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Source.StateUSPS, Source.StateName, Source.ZIP, Source.TimeOffset, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Source.DaylightSavingTime, Source.StartDateID, Source.CurrentFlag, Source.BatchID, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Source.LineageID, Source.CubeInd, Source.SortOrder, Source.Hash&lt;BR&gt;&amp;nbsp;&amp;nbsp;)&lt;BR&gt;&amp;nbsp;OUTPUT $action, inserted.CityName, inserted.CountyFIPS, inserted.CountyName, inserted.StateFIPS, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;inserted.StateUSPS, inserted.StateName, inserted.ZIP, inserted.TimeOffset, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;inserted.DaylightSavingTime, inserted.StartDateID, inserted.CurrentFlag, inserted.BatchID, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;inserted.LineageID, inserted.CubeInd, inserted.SortOrder, inserted.Hash&lt;BR&gt;)&lt;BR&gt;AS T &lt;BR&gt;(&lt;BR&gt;&amp;nbsp;action, CityName, CountyFIPS, CountyName, StateFIPS, &lt;BR&gt;&amp;nbsp;StateUSPS, StateName, ZIP, TimeOffset, &lt;BR&gt;&amp;nbsp;DaylightSavingTime, StartDateID, CurrentFlag, BatchID, &lt;BR&gt;&amp;nbsp;LineageID, CubeInd, SortOrder, Hash&lt;BR&gt;)&lt;BR&gt;WHERE action = 'UPDATE';&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;As mentioned, the OUTPUT clause on the inner MERGE statement feeds the outer INSERT clause.&amp;nbsp; Next stop&amp;nbsp;is &lt;A title="SQLSaturday #61 DC" href="http://www.sqlsaturday.com/61/schedule.aspx"&gt;SQLSaturday #61 in&amp;nbsp;DC&lt;/A&gt; at the beginning of December.&lt;/P&gt;</description></item><item><title>Find a Hash Collision, Win $100</title><link>http://sqlblog.com/blogs/michael_coles/archive/2010/04/17/find-a-hash-collision-win-100.aspx</link><pubDate>Sat, 17 Apr 2010 21:38:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:24374</guid><dc:creator>Mike C</dc:creator><description>&lt;P&gt;Margarity Kerns recently published a very nice article at SQL Server Central on &lt;A href="http://www.sqlservercentral.com/articles/Data+Warehouse/69679/"&gt;using hash functions to detect changes&lt;/A&gt; in rows during the data warehouse load ETL process.&amp;nbsp; On the discussion page for the article I noticed a lot of the same old arguments against using hash functions to detect change.&amp;nbsp; After having this same discussion several times over the past several months in public and private forums, I've decided to see if we can't put this argument to rest for a while.&amp;nbsp; To that end I'm going to hold a little contest:&amp;nbsp; &lt;B&gt;Generate an SHA-1 hash collision and win $100 and a book&lt;/B&gt; (see bottom section for details).&amp;nbsp; Before I get into the details of the contest I'm going to give a little background of how this came about.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;U&gt;Background Info&lt;/U&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;NOTE: If you aren't familiar with hash functions I highly recommend first reading the Wikipedia article at &lt;A href="http://en.wikipedia.org/wiki/Cryptographic_hash_function"&gt;http://en.wikipedia.org/wiki/Cryptographic_hash_function&lt;/A&gt;.&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;The idea of using a hash function for change detection is not new.&amp;nbsp; Essentially a hash function generates a "fingerprint" of your data that you can use to compare an inbound row and an existing row.&lt;/P&gt;
&lt;P&gt;Some people are wary of hash functions because they map a theoretically infinite number of large inputs to a much smaller finite set of hash values.&amp;nbsp; Most of the arguments people make against using hash functions for change detection boil down to variations of Murphy's Law:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;"There's a chance of a &lt;I&gt;hash&lt;/I&gt; &lt;I&gt;collision&lt;/I&gt; [generating the same hash value for two different inputs], so a collision &lt;I&gt;will&lt;/I&gt; happen!"&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;People have different ways of dealing with this issue, including taking one of the following positions:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The chance of collision is negligible so no additional precautions are required.&lt;/LI&gt;
&lt;LI&gt;A collision will absolutely happen so I won't use hash functions for change detection at all!&lt;/LI&gt;
&lt;LI&gt;A collision may happen so I want to use hash values only to initially narrow down the number of rows I need to compare fully.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Positions #1 and #2 above are at different ends of the spectrum.&amp;nbsp; Position #3 sits in the middle as a compromise solution.&amp;nbsp; While compromises may make for good politics, they often make for terrible technical solutions, as I'll discuss below.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;U&gt;Position #1: Odds of Collision are Low Enough to be Ignored&lt;/U&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;As far as position #1 is concerned, it depends on which hash function you're using.&amp;nbsp; You need to choose a true one-way &lt;I&gt;collision-free&lt;/I&gt;* cryptographic hash function with a wide bit length.&amp;nbsp; I normally recommend an SHA-2 hash function (256, 384 or 512 bit hash value), or when that's not available the SHA-1 160 bit hash function.&amp;nbsp; The odds of generating a collision with a 160 bit hash function are 2^80.&amp;nbsp; That is to say&amp;nbsp;you can expect a collision after you generate hashes for 1,208,925,819,614,629,174,706,176 rows of data.&lt;/P&gt;
&lt;P&gt;Of course if you're identifying rows by their natural or business keys this alternatively means you need to generate 1,208,925,819,614,629,174,706,176 variations of that single row before you'll hit a collision with SHA-1.&lt;/P&gt;
&lt;P&gt;To put that number in perspective, consider that Google processes 20,000,000,000,000,000 bytes (20 petabytes) of data per day.&amp;nbsp; If you were to store a single row in a database table for &lt;I&gt;every single byte&lt;/I&gt; Google processes each day, it would take you 60,446,290 days (approximately 156,600 years) to store 1,208,925,819,614,629,174,706,176 rows in that table.&lt;/P&gt;
&lt;P&gt;I personally assume position #1 on this subject, with the assumption that you have chosen a good solid hash function for the job.&amp;nbsp; More on this later.&lt;/P&gt;
&lt;P&gt;*A &lt;I&gt;collision-free&lt;/I&gt; cryptographic hash function is a one-way hash function with negligible probability of generating the same hash value for two different inputs. SHA-1 and SHA-256 are examples of collision-free cryptographic hash functions.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;U&gt;Position #2: I Don't Trust Hash Functions&lt;/U&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;This position can't really be argued with.&amp;nbsp; As shown above the odds of a collision with SHA-1 or another collision-free hash function are extremely low.&amp;nbsp; But if you don't trust it, you just don't trust it.&amp;nbsp; So the alternative is to compare every inbound column with every existing column.&amp;nbsp; It will cost you in efficiency on wide tables, but if you're not concerned about processing power, server resources&amp;nbsp;and execution time this classic method of change detection is well-proven to be 100% effective.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;U&gt;Position #3: The Compromise - Use Hash Values to Initially Narrow Down Results&lt;/U&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;This position is the compromise position that combines the implementation of #1 and #2 above.&amp;nbsp; It sounds wonderful in theory - use a hash function to narrow down your results, eliminating rows that don't need to be compared column by column; then compare all of the columns in the remaining rows that haven't been eliminated.&amp;nbsp; So let's look at a scenario:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;You are processing Row A through your ETL process into a target table. &amp;nbsp;Row B is the equivalent row in the target table (it has the same natural key/business key as Row A).&amp;nbsp; This assumes we are first locating the equivalent row in the target table by natural key/business key of the incoming row.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;There are three possible scenarios:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Row B exists in the target table, and is equal to Row A (no change).&lt;/LI&gt;
&lt;LI&gt;Row B exists in the target table, but it is not equal to Row A (update).&lt;/LI&gt;
&lt;LI&gt;Row B does not exist in the target table (insert Row A).&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Let's say you've generated two hash values, h(A) is the hash for Row A and h(B) is the hash for Row B.&amp;nbsp; Now we need to use h(A) and h(B) to eliminate rows to get rid of the extra column by column comparisons.&amp;nbsp; Here are the rules you need to implement to use h(A) and h(B) to eliminate extra comparisons in this compromise solution:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;A.&amp;nbsp; &lt;STRONG&gt;h(A) is equal to h(B)&lt;/STRONG&gt;: according to the compromise, if h(A) = h(B) we need to compare all columns of the inbound row against the existing row since the belief is that the hash function can/will generate collisions.&amp;nbsp; The idea is that h(A) may have generated the same value as h(B) even if A &amp;lt;&amp;gt; B.&amp;nbsp; So we need to:&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;BLOCKQUOTE&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;(1)&amp;nbsp; Compare all columns in A and B.&amp;nbsp; If A = B then perform no action.&lt;/P&gt;
&lt;P&gt;(2)&amp;nbsp; Compare all columns in A and B.&amp;nbsp; If A &amp;lt;&amp;gt; B then update.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/BLOCKQUOTE&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;B.&amp;nbsp; &lt;STRONG&gt;h(A) is not equal to h(B)&lt;/STRONG&gt;: cryptographic hash functions guarantee that they will generate the same hash value for the exact same inputs.&amp;nbsp; So we can eliminate full row comparisons if h(A) &amp;lt;&amp;gt; h(B).&amp;nbsp; We know automatically that if h(A) &amp;lt;&amp;gt; h(B) then A &amp;lt;&amp;gt; B.&amp;nbsp; Just perform the update.&lt;/P&gt;
&lt;P&gt;C.&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;h(B) is NULL&lt;/STRONG&gt;: that is, if Row B does not exist in the target table than h(B) is NULL.&amp;nbsp; This is a case where no further full-row comparisons are necessary.&amp;nbsp; Just insert the row.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now consider a slowly changing dimension (SCD) in a datamart application.&amp;nbsp; Many SCDs change slowly over time (hence the name &lt;I&gt;slowly&lt;/I&gt; changing dimension).&amp;nbsp; This means that new rows (updates and inserts) are far less common than receiving duplicate rows during ETL.&amp;nbsp; So the vast majority of your inbound data will fall under rule A(1) above.&amp;nbsp; So you're still performing comparisons of all columns for the vast majority of rows in a given table just to figure out that you don't need to update them after all!&lt;/P&gt;
&lt;P&gt;If you eliminate even 90% of the inbound rows under rule A(1) above you haven't saved much processing (you're still comparing all columns for changes for 90% of your inbound rows).&amp;nbsp; You probably actually cost yourself a lot of time and efficiency since you haven't accounted for the overhead of generating hash values for 100% of the inbound rows.&lt;/P&gt;
&lt;P&gt;The only way this compromise is more efficient is if a very large percentage of your inbound rows (much greater than 50+%) are inserts under Rule C or updates under Rule B above.&amp;nbsp; If the majority of your inbound rows are duplicates of existing rows under Rule A, you gain nothing.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;&lt;U&gt;The Contest&lt;/U&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;One-way collision-free cryptographic hash functions are supposed to have negligible probability of a hash collision, or two different inputs generating the same output.&amp;nbsp; Hash collisions are what cause change detection with hashes to fail.&lt;/P&gt;
&lt;P&gt;For instance, consider the following example of an MD5 hash collision:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;DECLARE @A varbinary(8000),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @B varbinary(8000),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @hA binary(16),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @hB binary(16);&lt;BR&gt;&lt;BR&gt;SELECT @A = 0xd131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @B = 0xd131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70;&lt;BR&gt;&lt;BR&gt;SELECT @hA = HASHBYTES('MD5', @A),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @hB = HASHBYTES('MD5', @B);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;SELECT CASE WHEN @A = @B&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; THEN '@A Equals @B'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ELSE '@A Is Not Equal To @B'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; END AS AB_Equal,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CASE WHEN @hA = @hB&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; THEN '@hA Equals @hB'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ELSE '@hA Is Not Equal To @hB'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; END AS Hash_Equal;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The results are shown below:&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:474px;HEIGHT:130px;" src="http://e60ybw.bay.livefilestore.com/y1psxBkasfIDMgAHCMabS5PLB9ude1BiCrYSrlnX0bKKCpRgSTnMBYiy4gA2uLRjr5Tpf1Feki0LZ6WmJEDJiEl46UECVjVfPpt/hash_not_equal.png" width=474 height=130&gt;&lt;/P&gt;
&lt;P&gt;When you run this you'll notice that the query reports the two source varbinary strings @A and @B are not equal, yet the two MD5 hashes they generate are equal.&amp;nbsp; This is an example of a simple hash collision with MD5.&lt;/P&gt;
&lt;P&gt;Now the challenge is to populate the following script with two different binary values that generate the same hash value.&amp;nbsp; The output should be the same as shown above in the MD5 example.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;--&amp;nbsp; Begin script&lt;BR&gt;DECLARE @A varbinary(8000),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @B varbinary(8000),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @hA binary(20),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @hB binary(20);&lt;BR&gt;&lt;BR&gt;-- Replace the &lt;EM&gt;?&lt;/EM&gt; below with binary strings&lt;BR&gt;&lt;BR&gt;SELECT @A = &lt;EM&gt;?&lt;/EM&gt;,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @B = &lt;EM&gt;?&lt;/EM&gt;;&lt;BR&gt;&lt;BR&gt;SELECT @hA = HASHBYTES('SHA1', @A),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @hB = HASHBYTES('SHA1', @B);&lt;BR&gt;&lt;BR&gt;SELECT CASE WHEN @A = @B&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; THEN '@A Equals @B'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ELSE '@A Is Not Equal To @B'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; END AS AB_Equal,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CASE WHEN @hA = @hB&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; THEN '@hA Equals @hB'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ELSE '@hA Is Not Equal To @hB'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; END AS Hash_Equal;&lt;BR&gt;-- End script&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The first person who sends me an example of two varbinary strings that generate the same SHA1 hash value will win $100 (US$) and a copy of my book &lt;A href="http://www.amazon.com/T-SQL-2008-Programmer-rsquo-Guide/dp/143021001X"&gt;Pro T-SQL 2008 Programmer's Guide&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;And here are the inevitable conditions:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;B&gt;No NULLs.&lt;/B&gt;&amp;nbsp; @A and @B in the script above cannot be set to NULL for purposes of this contest.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;8,000 bytes or less.&lt;/B&gt;&amp;nbsp; The T-SQL HASHBYTES function accepts varbinary(8000) values, so the values passed into it in this contest must be 8,000 bytes in length or less.&amp;nbsp; The values assigned to @A and @B above must be 8,000 bytes or less in length.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;No unnecessary changes to the script.&lt;/B&gt;&amp;nbsp; The only change allowed to the script above are the replacement of the question marks (?) with binary strings.&amp;nbsp; No other changes to the script are authorized.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;Only one person will win.&lt;/B&gt;&amp;nbsp; The first person who sends me a copy of the above script with two different binary values that generate an SHA-1 hash collision will win.&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;Void where prohibited.&lt;/B&gt;&amp;nbsp; Obviously if contests like this aren't legal in your country, state, county, city, etc. then you can't take part.&amp;nbsp; Petition your government to make it legal :)&lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;Time limits.&lt;/B&gt;&amp;nbsp; Entries must be received prior to midnight U.S. Eastern Standard Time on October 31, 2010.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Decisions of the judge are final.&lt;/STRONG&gt;&amp;nbsp; For purposes of this contest that would be me.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;SQL Server 2005 or 2008.&lt;/STRONG&gt;&amp;nbsp; Entries must be runnable on&amp;nbsp;SQL Server 2005 and SQL Server 2008 Developer Edition, and the results must be reproducible.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;If a winning entry is received prior to the deadline, I'll post an update entry to the blog with the winning script and the name of the winner.&lt;/P&gt;</description></item><item><title>T-SQL Tuesday #005: Creating SSMS Custom Reports</title><link>http://sqlblog.com/blogs/michael_coles/archive/2010/04/12/t-sql-tuesday-005-creating-ssms-custom-reports.aspx</link><pubDate>Tue, 13 Apr 2010 00:14:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:24228</guid><dc:creator>Mike C</dc:creator><description>&lt;P&gt;This is my&amp;nbsp;contribution to the T-SQL Tuesday blog party, started by &lt;A title="Adam Machanic" href="http://sqlblog.com/blogs/adam_machanic/archive/2010/04/05/t-sql-tuesday-005-reporting.aspx"&gt;Adam Machanic&lt;/A&gt; and &amp;nbsp;hosted this month by &lt;A title="Aaron Nelson" href="http://sqlvariant.com/wordpress/index.php/2010/04/t-sql-tuesday-005-reporting/"&gt;Aaron Nelson&lt;/A&gt;.&amp;nbsp; Aaron announced this month's topic is "reporting" so I figured I'd throw a blog up on a reporting topic I've been interested in for a while -- namely creating custom reports in SSMS.&lt;/P&gt;
&lt;P&gt;Creating SSMS custom reports isn't difficult, but&amp;nbsp;like most technical work it's very detailed with a lot of little steps involved.&amp;nbsp; So this post is a little longer than usual and includes a lot of screenshots.&amp;nbsp; There's also a downloadable &lt;A title="Sample SSMS Custom Reports" href="http://brprfa.bay.livefilestore.com/y1pu65YtRksdmF-NkqPRSNVJVjP75MjU31Yyvna97r9AoEdF9wilfgmWTFCpm7DDuuPRpS9qe9Io-h4_pms-Y2N0LV1L6j8bNeU/Custom%20Report%20Samples.zip?download"&gt;ZIP file&lt;/A&gt; with the projects from this article included.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;SSMS Custom Reports&lt;/U&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;SQL Server 2008 and 2005 both offer custom report functionality in Management Studio.&amp;nbsp; With a little bit of work you can create custom SSMS reports just like the standard reports that Microsoft ships with Management Studio.&amp;nbsp; The Disk Usage Report shown below is just one of the many standard reports that comes with SSMS.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:591px;HEIGHT:496px;" title="SSMS Standard Report" alt="SSMS Standard Report" src="http://brprfa.bay.livefilestore.com/y1p96w-RdpK_UPoOGMgli4eVbzYi3Oj9d-SdGVX4zXdkABiCseQUqv8_Ye9DjYtHHdaJj39eOK0XzLEqnctlccDKSptvHhJME1c/standard-report.jpg" width=591 height=496&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Creating a Report Project&lt;/U&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;SSMS uses the SQL Server Reporting Services (SSRS) 2005 client/viewer control to render both standard and custom reports.&amp;nbsp; This is true for both SSMS 2005 and SSMS 2008.&amp;nbsp; So the first step to building a custom SSMS report is to fire up Visual Studio 2005 and create a new &lt;EM&gt;Report Server Project&lt;/EM&gt; as shown below.&amp;nbsp; For this example we'll create a custom report that lists missing indexes, so give the project the name &lt;I&gt;Missing Index&lt;/I&gt;.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:550px;HEIGHT:305px;" title="Create New Project Dialog" alt="Create New Project Dialog" src="http://brprfa.bay.livefilestore.com/y1pkwKN2ypKEv3XJHROh7xaoTOi4R79ha01zyZnL-acBQhieH_6CAo18PEri6DjOBX5d_O2jgH6bPTvIOUWNpmr7eHf-4xxG_GI/vs2005-new-project.jpg" width=550 height=305&gt;&lt;/P&gt;
&lt;P&gt;Once you create the &lt;EM&gt;Report Server Project&lt;/EM&gt; right-click on &lt;I&gt;Reports&lt;/I&gt; in the Solution Explorer and choose &lt;I&gt;Add &amp;gt; New Item...&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:286px;HEIGHT:258px;" title="Add Report to Project" alt="Add Report to Project" src="http://brprfa.bay.livefilestore.com/y1p8qFbsxsFq7xjtkvppNWQ-N7S5R-uoHiJif6FtkChY1pzf5qQblwl7AapydMWrSRFY1_O-XsadEk5nR6XV9DX7-2lJVp7TFWn/add-report.jpg" width=286 height=258&gt;&lt;/P&gt;
&lt;P&gt;When the &lt;I&gt;Add New Item&lt;/I&gt; box appears, choose the Report template and give the report a name.&amp;nbsp;&amp;nbsp;For this example I named the report&amp;nbsp;&lt;I&gt;Missing Index.rdl&lt;/I&gt; - the &lt;EM&gt;.rdl&lt;/EM&gt; extension stands for "Report Definition Language", and is the standard extension for SSRS report definition files.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:551px;HEIGHT:244px;" title="Add Report Dialog" alt="Add Report Dialog" src="http://brprfa.bay.livefilestore.com/y1pf_VVyzWAjA0uiWHfEChyN-uwUNscnR9B5cHDipw1KDF1StNazv-T7xFtmGqtdgBVZ1kGS_daR5vqkPFk-QdqpWMVdDR5Nodv/add-report-box.jpg" width=551 height=244&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Defining the Report Dataset&lt;/U&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Once the report is added to your project you have to add a new dataset to the report.&amp;nbsp; The dataset defines the structure and content of the source data that will populate your report.&amp;nbsp; Choose &lt;I&gt;&amp;lt;New Dataset...&amp;gt;&lt;/I&gt; from the &lt;I&gt;Dataset:&lt;/I&gt; dropdown.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:470px;HEIGHT:151px;" title="Add New Dataset dropdown" alt="Add New Dataset dropdown" src="http://brprfa.bay.livefilestore.com/y1pw8BZ2mr9F4SCExKCklLxVPczZu6Mq0IEo2agULy1QRoLJRF2KKDqVAv1Oft41oQu1oBaZd_iEMa91OfLT83Eeky87qAra11Z/add-new-dataset.jpg" width=470 height=151&gt;&lt;/P&gt;
&lt;P&gt;Visual Studio will respond with a &lt;EM&gt;Data Source&lt;/EM&gt; box.&amp;nbsp; Just make sure the &lt;I&gt;Type:&lt;/I&gt; dropdown is set to the default &lt;STRONG&gt;Microsoft SQL Server&lt;/STRONG&gt; and put &lt;STRONG&gt;Data Source=.&lt;/STRONG&gt; in the &lt;I&gt;Connection string:&lt;/I&gt; box.&amp;nbsp; This is all that's required since the SSMS custom report you're creating will use connections created and managed by SSMS's Object Explorer.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:569px;HEIGHT:487px;" title="Add Datasource Dialog" alt="Add Datasource Dialog" src="http://brprfa.bay.livefilestore.com/y1pZ9v1Nf3IVwj1bm5gCsMnZLstJyKbsLFI75DOGhsuGjcuHZalsEs2c_odVbbgaqiWQpwyYZkyRBc3BExbXiZweT67vn5FhBgN/add-data-source.jpg" width=569 height=487&gt;&lt;/P&gt;
&lt;P&gt;After you define the data source, you can define the SQL query that will populate your report.&amp;nbsp; Just put the query in the dataset window as shown below.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:703px;HEIGHT:358px;" title="Adding a Dataset" alt="Adding a Dataset" src="http://brprfa.bay.livefilestore.com/y1pfTvR7VFHggCKt2l8yVZ_2vlxY9-ZppnqW2MEJIDTQvzy1X7zhLg43LfaTKpRB2QI5rlzv_TcpiCKkbXPh7WQZL5d-a6PNLdP/add-new-dataset3.jpg" width=703 height=358&gt;&lt;/P&gt;
&lt;P&gt;I borrowed (and slightly modified) the following query from &lt;A title="Brent Ozar!" href="http://www.brentozar.com/"&gt;Brent Ozar&lt;/A&gt;.&amp;nbsp; He originally published it at &lt;A title=SQLServerPedia! href="http://sqlserverpedia.com/wiki/Find_Missing_Indexes"&gt;SQLServerPedia&lt;/A&gt;. &amp;nbsp;This particular query uses SQL Server's missing index Dynamic Management Views (DMVs) to identify missing indexes.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;-- Begin missing index query&lt;BR&gt;&lt;BR&gt;WITH cte&lt;BR&gt;AS&lt;BR&gt;(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT mid.object_id AS object_id,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; QUOTENAME(OBJECT_SCHEMA_NAME(mid.object_id)) AS table_schema,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; QUOTENAME(OBJECT_NAME(mid.object_id)) AS table_name,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; QUOTENAME('IX_' + OBJECT_SCHEMA_NAME(mid.object_id) + '_' +&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LEFT(CAST(NEWID() AS CHAR(36)), 8)) AS index_name,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mid.index_handle&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM sys.dm_db_missing_index_details mid&lt;BR&gt;)&lt;BR&gt;SELECT&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DENSE_RANK() OVER&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ORDER BY cte.table_schema, cte.table_name&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) AS table_color,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ROW_NUMBER() OVER&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PARTITION BY cte.table_schema, cte.table_name&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ORDER BY (avg_total_user_cost * avg_user_impact) * (user_seeks + user_scans) DESC&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) AS index_color,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cte.table_schema,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cte.table_name,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cte.index_name AS index_name,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (avg_total_user_cost * avg_user_impact) * (user_seeks + user_scans) AS calc_impact,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'CREATE NONCLUSTERED INDEX ' + cte.index_name + ' ON ' +&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cte.table_schema + '.' + cte.table_name +&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' (' + COALESCE(mid.equality_columns, '') +&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CASE WHEN mid.inequality_columns IS NULL&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; THEN ''&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ELSE CASE WHEN mid.equality_columns IS NULL&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; THEN ''&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ELSE ','&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; END + mid.inequality_columns&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; END +&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ') ' + CASE WHEN mid.included_columns IS NULL&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; THEN ''&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ELSE 'INCLUDE (' + mid.included_columns + ')'&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; END +&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ';' AS create_stmt,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mid.equality_columns,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mid.inequality_columns,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mid.included_columns &lt;BR&gt;FROM sys.dm_db_missing_index_group_stats AS migs &lt;BR&gt;INNER JOIN sys.dm_db_missing_index_groups AS mig&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ON migs.group_handle = mig.index_group_handle &lt;BR&gt;INNER JOIN sys.dm_db_missing_index_details AS mid&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ON mig.index_handle = mid.index_handle&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AND mid.database_id = DB_ID() &lt;BR&gt;INNER JOIN cte&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ON cte.index_handle = mid.index_handle&lt;BR&gt;WHERE migs.group_handle IN &lt;BR&gt;(&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT group_handle&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM sys.dm_db_missing_index_group_stats WITH (NOLOCK) &lt;BR&gt;)&lt;BR&gt;ORDER BY calc_impact DESC;&lt;BR&gt;&lt;BR&gt;-- End missing index query&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;There are a couple of caveats to keep in mind about the missing index DMVs that this query relies on:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;They're not designed to be exhaustive.&amp;nbsp; If you want to get a serious analysis of useful indexes in your databases, you definitely want to use a tool that will perform a more extensive analysis.&lt;/LI&gt;
&lt;LI&gt;The DMVs only persist their information since the last time the SQL Server service was restarted.&amp;nbsp; If you've recently restarted the service you'll get very little information back.&amp;nbsp; These DMVs are best to use when your server has been running under normal load for a while.&lt;/LI&gt;
&lt;LI&gt;The suggestions returned by the DMVs aren't always the best way to go.&amp;nbsp; These DMVs often recommend suggested indexes with lots of overlap (lots of columns in common, often in similar order).&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;To put it another way, don't take the raw information returned by these DMVs at face value.&amp;nbsp; The information they return is definitely useful for determining where indexes might provide benefit if your system has been running under normal load for a while, and the redundant index suggestions tend to indicate which indexes might be most useful.&amp;nbsp; But these DMVs just amount to a starting point for analyzing your indexing needs.&amp;nbsp; I'd recommend against creating dozens of redundant&amp;nbsp;indexes based on the raw output of these DMVs.&lt;/P&gt;
&lt;P&gt;Visual Studio will normally populate the dataset fields.&amp;nbsp; If for some reason it doesn't, you can manually edit the fields by hitting the&amp;nbsp;&lt;IMG style="WIDTH:12px;HEIGHT:11px;" title="Edit Selected Dataset button" alt="Edit Selected Dataset button" src="http://brprfa.bay.livefilestore.com/y1p1RjlRPeT8nUiaHkby2NgdTPdwAZhlX8j1xno7j2uXjLVrCXDh4iCA3tat3aKVR2mak4Anfa_irdyFjJ8vd1qRUXFznVjXJLl/edit-selected-dataset.jpg" width=25 height=22&gt;&amp;nbsp;&lt;I&gt;Edit Selected Dataset&lt;/I&gt; button to pull up the &lt;I&gt;Dataset&lt;/I&gt; window.&amp;nbsp; You can then enter the field names on the &lt;I&gt;Fields&lt;/I&gt; tab if they aren't already populated.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:388px;HEIGHT:319px;" title="Edit Dataset Fields tab" alt="Edit Dataset Fields tab" src="http://brprfa.bay.livefilestore.com/y1pfvnIF4EbFtuA6q8rBYk0t072J_cDu43NCKGn3DGtJepbF5Xtr-qqAQ23gcmmMQr94DH295woheHjRbkSBuXMC-oHJsxPlDoL/dataset-fields.jpg" width=554 height=458&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Building the Report&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So far most of what we've done is just setup.&amp;nbsp; With this&amp;nbsp;done, it's time to design and build the actual report.&amp;nbsp; For this, click on the Visual Studio &lt;EM&gt;Layout&lt;/EM&gt; tab to get to the report designer surface.&amp;nbsp; You can drag and drop text boxes, charts, tables, images and any other controls from the Toolbox onto the designer surface.&amp;nbsp; To keep it simple we'll just drag a text box and a table onto the designer.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:685px;HEIGHT:341px;" title="Reprot Designer Layout tab" alt="Reprot Designer Layout tab" src="http://brprfa.bay.livefilestore.com/y1pWNM-fc_9Nr_h6im9m8v9jweJclU9QXhuvkIMwSDMxkaDXMq_QqvgLUJN3wtzqqQil54T4aTHvvDOFPupnH2D_i0WQAhx9u2G/report-designer-1.jpg" width=685 height=341&gt;&lt;/P&gt;
&lt;P&gt;Put the title of the report in the text box (in this case "Missing Index Report") and format it to your liking.&amp;nbsp; The table we dragged onto the designer surface has three columns by default.&amp;nbsp; For this example we want six columns total.&amp;nbsp; To add more columns right-click on the top border of the table and choose &lt;I&gt;Insert Column to the Left&lt;/I&gt; to add a new column.&amp;nbsp; Repeat two more times.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:516px;HEIGHT:265px;" title="Inserting columns in SSRS table" alt="Inserting columns in SSRS table" src="http://brprfa.bay.livefilestore.com/y1pMVVRej-iyVngxatXV5eZNwxe42KRX3loOI5AMNbJYNPvaQLwNPdA2_rEfbFqaXJ1M827zxGteCq8wtIkw8mJmOigbBDgloik/insert-columns.jpg" width=831 height=459&gt;&lt;/P&gt;
&lt;P&gt;In the &lt;I&gt;Header&lt;/I&gt; row of the table we'll type in the headers for each column like the following:&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:577px;HEIGHT:173px;" title="Editing Table Column Headers in a report" alt="Editing Table Column Headers in a report" src="http://brprfa.bay.livefilestore.com/y1pclRRkvyQ58kZth8uxowVdjARwR9LROwxTNmOxKph-la2SwSyk5UdkLqGTrgDQVNk1bi-Q4A9YX_8RUluiCHCba_EI6APPNOz/report-column-headers.jpg" width=968 height=303&gt;&lt;/P&gt;
&lt;P&gt;In the &lt;I&gt;Detail&lt;/I&gt; row we'll put in the formulas to populate the database fields like this:&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:579px;HEIGHT:181px;" title="Editing the Report Table Details" alt="Editing the Report Table Details" src="http://brprfa.bay.livefilestore.com/y1pCcKPNTXmgXVchY8WkAtQYF-L5iPN8g65mJC8cHhd0fJ7O3tPx4iAHmhWO7XrQG8VXQ-c2p-pUE01v5noF_nqihOBBaQ9d15j/report-column-details.jpg" width=968 height=303&gt;&lt;/P&gt;
&lt;P&gt;SSRS formulas begin with the equal sign (&lt;STRONG&gt;=&lt;/STRONG&gt;).&amp;nbsp; Fields from the dataset are referenced directly using the format &lt;EM&gt;&lt;STRONG&gt;Fields!field_name.Value&lt;/STRONG&gt;&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Deploying and Running the Report&lt;/U&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;At this point use Visual Studio to build the project.&amp;nbsp; Once it builds without error, navigate to the project directory in Windows Explorer and copy the &lt;I&gt;Missing Index.rdl&lt;/I&gt; file to the SSMS Custom Reports directory (on my computer this directory is located at &lt;EM&gt;C:\Users\Michael\Documents\SQL Server Management Studio\Custom Reports&lt;/EM&gt;, it'll be different on yours).&amp;nbsp; &lt;/P&gt;
&lt;P&gt;You can now bring up this report in SSMS by right-clicking on a database in the Object Explorer and selecting &lt;I&gt;Reports &amp;gt; Custom Reports...&lt;/I&gt; to select the custom report.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:350px;HEIGHT:322px;" title="Running a Custom Report in SSMS" alt="Running a Custom Report in SSMS" src="http://brprfa.bay.livefilestore.com/y1pXFRn1jsLwq2U9tpYrjStVVVnrG-A7RO2mZfEAd_tZPMUVN1X3VRrc81PtQl8l0TcHgCFIMa3dPDSb1qhAxRvyxu8vL94iaPB/run-custom-report.jpg" width=567 height=551&gt;&lt;/P&gt;
&lt;P&gt;Choose your custom report from the file selection box and click &lt;I&gt;Open&lt;/I&gt;.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:543px;HEIGHT:340px;" title="Selecting a Custom Report in SSMS" alt="Selecting a Custom Report in SSMS" src="http://brprfa.bay.livefilestore.com/y1pwUOidWktlB26rl2DefIcRZ4YzSDVRUwqZ3IqFDNh3mAEvNg9Fs-Gy8k8m5lnVJfSPm3dEb6GNQpOXGdsK2u1ABViZ4cHivzr/choose-custom-report.jpg" width=864 height=543&gt;&lt;/P&gt;
&lt;P&gt;When you run a custom report in SSMS you'll get a warning like the following:&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:306px;HEIGHT:186px;" title="SSMS Custom Report Warning Box" alt="SSMS Custom Report Warning Box" src="http://brprfa.bay.livefilestore.com/y1pj7c9vCxvKz3cPrIDZuL5EIvxHJGN6FlCspgGan0cZdd08mvzz0CKuUbdxcfbKA-hPSJU4F9pP6BJb08s1vLqurCuKhYMWDHe/custom-report-warning.jpg" width=420 height=256&gt;&lt;/P&gt;
&lt;P&gt;Just choose &lt;EM&gt;Run&lt;/EM&gt;.&amp;nbsp; You might also want to check the box that says "&lt;EM&gt;Please don't show this warning again&lt;/EM&gt;" to keep the box from popping up every time you run a custom report.&amp;nbsp; The simple custom report you've created looks like the one shown below.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:593px;HEIGHT:254px;" title="Simple Custom Report" alt="Simple Custom Report" src="http://brprfa.bay.livefilestore.com/y1pTSsqYVoiCmzuzPOOHutMQnibG2CwxjGijBWma-J9VL3XPF1P0CpVzbQUUbGUj9vXmYh0avAt7armpL4BnSvxub7pcAq8xT3O/simple-report.jpg" width=964 height=453&gt;&lt;/P&gt;
&lt;P&gt;You can use images, color and other formatting techniques to make the report easier to read and use, and more flexible for your users.&amp;nbsp; Consider the image below, which is a screenshot of a reformatted version of the &lt;EM&gt;Missing Index&lt;/EM&gt; report.&amp;nbsp; This one includes more information, color and collapsible sections.&amp;nbsp; Both reports are included in the attached &lt;A title="SSMS Custom Reports" href="http://brprfa.bay.livefilestore.com/y1pu65YtRksdmF-NkqPRSNVJVjP75MjU31Yyvna97r9AoEdF9wilfgmWTFCpm7DDuuPRpS9qe9Io-h4_pms-Y2N0LV1L6j8bNeU/Custom%20Report%20Samples.zip?download"&gt;ZIP file&lt;/A&gt; under the Missing Index and Missing Index Color directories.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:601px;HEIGHT:488px;" title="Reformatted SSMS Custom Report" alt="Reformatted SSMS Custom Report" src="http://brprfa.bay.livefilestore.com/y1pHxjPdr2Zd4nKD0hsBC6T0BTOiIH15VmH6pfwHt3jfrod1z_bQ_dqEx6eDfZKCTt66KotLSPQXOOrX7F40Lwc3T05ZBCZGypG/final-report-color.jpg" width=991 height=810&gt;&lt;/P&gt;
&lt;P&gt;You can play around with the source files included in the attached &lt;A title="Sample SSMS Custom Reports" href="http://brprfa.bay.livefilestore.com/y1pu65YtRksdmF-NkqPRSNVJVjP75MjU31Yyvna97r9AoEdF9wilfgmWTFCpm7DDuuPRpS9qe9Io-h4_pms-Y2N0LV1L6j8bNeU/Custom%20Report%20Samples.zip?download" target=_blank&gt;ZIP file&lt;/A&gt;.&lt;/P&gt;</description></item><item><title>Bit-Twiddling in SQL</title><link>http://sqlblog.com/blogs/michael_coles/archive/2010/04/03/bit-twiddling-in-sql.aspx</link><pubDate>Sun, 04 Apr 2010 03:40:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:24024</guid><dc:creator>Mike C</dc:creator><description>&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;Someone posted a question to the SQL Server forum the other day asking how to count runs of zero bits in an integer using SQL.&amp;nbsp; Basically the poster wanted to know how to efficiently determine the longest contiguous string of zero-bits (known as a&amp;nbsp;run of bits) in any given&amp;nbsp;32-bit&amp;nbsp;integer.&amp;nbsp; Here are a couple of&amp;nbsp;examples to demonstrate the idea:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';FONT-SIZE:11pt;"&gt;Decimal = Binary = Zero Run&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';FONT-SIZE:11pt;"&gt;&lt;BR&gt;999,999,999 decimal = &lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;U&gt;&lt;SPAN style="COLOR:#0070c0;"&gt;00&lt;/SPAN&gt;&lt;/U&gt;&lt;/B&gt;111011 1&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;U&gt;&lt;SPAN style="COLOR:#0070c0;"&gt;00&lt;/SPAN&gt;&lt;/U&gt;&lt;/B&gt;11010 11&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;U&gt;&lt;SPAN style="COLOR:#0070c0;"&gt;00&lt;/SPAN&gt;&lt;/U&gt;&lt;/B&gt;1&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;U&gt;&lt;SPAN style="COLOR:#0070c0;"&gt;00&lt;/SPAN&gt;&lt;/U&gt;&lt;/B&gt;1 11111111 binary = 2 contiguous zero bits&lt;BR&gt;666,666,666 decimal = 00100111 10111100 1&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;U&gt;&lt;SPAN style="COLOR:#0070c0;"&gt;0000&lt;/SPAN&gt;&lt;/U&gt;&lt;/B&gt;110 10101010 binary = 4 contiguous zero bits&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;My first reaction was that SQL is not my first choice of a go-to language for bit twiddling hacks.&amp;nbsp; These types of calculations are generally most efficient in C-style compiled procedural languages with plenty of bit manipulation instructions that map almost directly one-for-one to low-level machine language instructions.&amp;nbsp; In all fairness, SQL does have some bit-level operators (&amp;amp;, |, etc. operators), but the performance isn’t as optimized as a language like C#.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;At any rate, a few different ideas were tossed around, like the simplistic loop-and-count procedural method.&amp;nbsp; Using this method you just keep a running total of the longest zero-bit run and keep looping over the bits, adjusting your running total, comparing to your largest run of zero bits, and shifting your integer one bit right each time.&amp;nbsp; But this being SQL, I decided to attack the problem from a set-based perspective.&amp;nbsp; To start with I built a 1,000,000 row table to hold random integers:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;FONT-SIZE:11pt;"&gt;CREATE&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';FONT-SIZE:11pt;"&gt; &lt;SPAN style="COLOR:blue;"&gt;TABLE&lt;/SPAN&gt; TempNum &lt;SPAN style="COLOR:gray;"&gt;&lt;BR&gt;(&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Num &lt;SPAN style="COLOR:blue;"&gt;BIGINT&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;NOT&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;NULL&lt;BR&gt;);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;GO&lt;BR&gt;&lt;BR&gt;WITH&lt;/SPAN&gt; GenerateRandom&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;AS&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&lt;/SPAN&gt; 1 &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; n&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:fuchsia;"&gt;ABS&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;CONVERT&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;BIGINT&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:fuchsia;"&gt;CONVERT&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;BINARY&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:fuchsia;"&gt;CHECKSUM&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;NEWID&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;())))&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;%&lt;/SPAN&gt; 4294967296&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; Random&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; UNION&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;ALL&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&lt;/SPAN&gt; n &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:fuchsia;"&gt;ABS&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;CONVERT&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;BIGINT&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:fuchsia;"&gt;CONVERT&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;BINARY&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:fuchsia;"&gt;CHECKSUM&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;NEWID&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;())))&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;%&lt;/SPAN&gt; 4294967296&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM&lt;/SPAN&gt; GenerateRandom&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHERE&lt;/SPAN&gt; n &lt;SPAN style="COLOR:gray;"&gt;&amp;lt;&lt;/SPAN&gt; 1000000&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;INSERT&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;INTO&lt;/SPAN&gt; TempNum &lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Num&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;SELECT&lt;/SPAN&gt; Random&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;FROM&lt;/SPAN&gt; GenerateRandom&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;OPTION &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;MAXRECURSION 0&lt;SPAN style="COLOR:gray;"&gt;);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;GO&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';FONT-SIZE:11pt;"&gt;&lt;SPAN style="COLOR:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;Note that I used SQL Server’s BIGINT data type (64-bit integer) since I wanted to deal only in unsigned 32-bit integers.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;For my initial crack at a solution I split the 32-bit integer up into individual bits and treated the whole thing like a classic Gaps and Islands problem.&amp;nbsp; Essentially the 1 bits are islands, the 0's are gaps, and the length of the longest gap is the correct answer.&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;FONT-SIZE:11pt;"&gt;DBCC&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';FONT-SIZE:11pt;"&gt; FREEPROCCACHE&lt;SPAN style="COLOR:gray;"&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;DBCC&lt;/SPAN&gt; DROPCLEANBUFFERS&lt;SPAN style="COLOR:gray;"&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;GO&lt;BR&gt;&lt;BR&gt;WITH&lt;/SPAN&gt; Powers&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;AS&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&lt;/SPAN&gt; 0 &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; id&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CAST&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;1 &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;BIGINT&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; pwr&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; UNION&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;ALL&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&lt;/SPAN&gt; p&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;id &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; POWER&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;CAST&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;2 &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;BIGINT&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt; p&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;id &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM&lt;/SPAN&gt; Powers p&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHERE&lt;/SPAN&gt; p.id &lt;SPAN style="COLOR:gray;"&gt;&amp;lt;&lt;/SPAN&gt; 33&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;),&lt;BR&gt;&lt;/SPAN&gt;Islands&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;AS&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&lt;/SPAN&gt; &lt;SPAN style="COLOR:fuchsia;"&gt;ROW_NUMBER&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;()&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;OVER &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;PARTITION&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;BY&lt;/SPAN&gt; tn&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:blue;"&gt;ORDER&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;BY&lt;/SPAN&gt; id&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; RowNum&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tn&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;id&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;pwr&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM&lt;/SPAN&gt; Powers p&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CROSS&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;JOIN&lt;/SPAN&gt; TempNum tn&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHERE&lt;/SPAN&gt; p&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;pwr &lt;SPAN style="COLOR:gray;"&gt;&amp;amp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;((&lt;/SPAN&gt;tn&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:gray;"&gt;*&lt;/SPAN&gt; 2 &lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;|&lt;/SPAN&gt; &lt;SPAN style="COLOR:fuchsia;"&gt;CAST&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;8589934593 &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;BIGINT&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;))&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;&amp;lt;&amp;gt;&lt;/SPAN&gt; 0&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;SELECT&lt;/SPAN&gt; c&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; Num&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MAX&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;n&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;id &lt;SPAN style="COLOR:gray;"&gt;-&lt;/SPAN&gt; c&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;id &lt;SPAN style="COLOR:gray;"&gt;-&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; ZeroBitRun&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;INTO&lt;/SPAN&gt; #Temp&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;FROM&lt;/SPAN&gt; Islands &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; c&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;INNER&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;JOIN&lt;/SPAN&gt; Islands &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; n&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ON&lt;/SPAN&gt; n&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;RowNum &lt;SPAN style="COLOR:gray;"&gt;=&lt;/SPAN&gt; c&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;RowNum &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; 1&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AND&lt;/SPAN&gt; n&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:gray;"&gt;=&lt;/SPAN&gt; c&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;WHERE&lt;/SPAN&gt; n&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;id &lt;SPAN style="COLOR:gray;"&gt;-&lt;/SPAN&gt; c&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;id &lt;SPAN style="COLOR:gray;"&gt;&amp;gt;&lt;/SPAN&gt; 1&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;GROUP&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;BY&lt;/SPAN&gt; c&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; n&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num&lt;SPAN style="COLOR:gray;"&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;GO&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';FONT-SIZE:11pt;"&gt;&lt;SPAN style="COLOR:blue;"&gt;&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;One interesting aside on this solution - to ensure that leading and trailing zeroes were counted for&amp;nbsp;every 32-bit number I had to shift the number left one bit (multiply by 2) and do&amp;nbsp;a bitwise OR (| operator) with 8589934593, setting both the lowest bit (bit 0) and the highest bit (bit 33) to 1.&amp;nbsp; Basically this means you’re now dealing with a 34-bit integer, with the highest and lowest bits counted as islands. &lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;This ensures that for the 32 bits in between leading and trailing gaps are correctly identified.&amp;nbsp; On my PC this query took an average of just over 360 seconds (6 minutes) to identify the largest run of zero bits in 1,000,000 random numbers.&amp;nbsp; Another solution posted to the group used logarithms combined with bit-shifting in a recursive CTE.&amp;nbsp; This one completed 1,000,000 iterations in about 17.5 minutes.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;I couldn't help but think that when you get down to it, a solution to this problem should play to SQL’s strengths.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;I decided that what I really need for an efficient SQL solution to this problem is a lookup table.&amp;nbsp; Granted, a lookup table of 4+ billion rows (one row for each and every 32 bit number) would take a long time to build and probably wouldn't lend itself to IO efficiencies in SQL Server.&amp;nbsp; So I opted for a scaled down version and built a lookup table of 65,536 rows with one row representing every possible 16 bit number.&amp;nbsp; There are a lot of clever ways to grab bit-level pattern information (Google "de Bruijn sequence", for instance), but to be honest this lookup table is a one-time build and static population so I decided to keep it simple.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;FONT-SIZE:11pt;"&gt;CREATE&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';FONT-SIZE:11pt;"&gt; &lt;SPAN style="COLOR:blue;"&gt;TABLE&lt;/SPAN&gt; #Nybbles&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Num &lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;primary&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;key&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;not&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;null,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; String &lt;SPAN style="COLOR:blue;"&gt;varchar&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;4&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;not&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;null,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Leading &lt;SPAN style="COLOR:blue;"&gt;tinyint&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;not&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;null,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Trailing &lt;SPAN style="COLOR:blue;"&gt;tinyint&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;not&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;null&lt;BR&gt;);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;GO&lt;BR&gt;&lt;BR&gt;INSERT&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;INTO&lt;/SPAN&gt; #Nybbles&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Num&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; String&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Leading&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Trailing&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;VALUES &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;0&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'0000'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 4&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 4&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;1&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'0001'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 3&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;2&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'0010'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 2&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;3&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'0011'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 2&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;/SPAN&gt;4&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'0100'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 2&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;5&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'0101'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;6&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'0110'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;7&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'0111'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;/SPAN&gt;8&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'1000'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 3&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;9&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'1001'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;10&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'1010'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;11&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'1011'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;/SPAN&gt;12&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'1100'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 2&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;13&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'1101'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;14&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'1110'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;),&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;15&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;'1111'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; 0&lt;SPAN style="COLOR:gray;"&gt;);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;GO&lt;BR&gt;&lt;BR&gt;CREATE&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;TABLE&lt;/SPAN&gt; #BitMask&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Length&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;tinyint&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Mask &lt;SPAN style="COLOR:blue;"&gt;varchar&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;16&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;GO&lt;BR&gt;&lt;BR&gt;WITH&lt;/SPAN&gt; GetMasks&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;AS&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&lt;/SPAN&gt; 0 &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;Length&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CAST&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;''&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;varchar&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;16&lt;SPAN style="COLOR:gray;"&gt;))&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; Mask&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; UNION&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;ALL&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;Length&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CAST&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;REPLICATE&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;'0'&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;Length&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; 1&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;varchar&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;16&lt;SPAN style="COLOR:gray;"&gt;))&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM&lt;/SPAN&gt; GetMasks&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHERE&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;Length&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;&amp;lt;&lt;/SPAN&gt; 16&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;INSERT&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;INTO&lt;/SPAN&gt; #BitMask&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Length&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Mask&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;SELECT&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;Length&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Mask&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;FROM&lt;/SPAN&gt; GetMasks&lt;SPAN style="COLOR:gray;"&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;GO&lt;BR&gt;&lt;BR&gt;CREATE&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;TABLE&lt;/SPAN&gt; BitPattern&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Num &lt;SPAN style="COLOR:blue;"&gt;int&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;not&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;null&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;primary&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;key&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Trailing &lt;SPAN style="COLOR:blue;"&gt;tinyint&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Leading &lt;SPAN style="COLOR:blue;"&gt;tinyint&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Seq &lt;SPAN style="COLOR:blue;"&gt;tinyint&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;GO&lt;BR&gt;&lt;BR&gt;WITH&lt;/SPAN&gt; GetBin&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;AS&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&lt;/SPAN&gt; n1&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:gray;"&gt;*&lt;/SPAN&gt; 4096 &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; n2&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:gray;"&gt;*&lt;/SPAN&gt; 256 &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; n3&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:gray;"&gt;*&lt;/SPAN&gt; 16 &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; n4&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; Num&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; n1&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;String &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; n2&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;String &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; n3&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;String &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; n4&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;String &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; String&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM&lt;/SPAN&gt; #Nybbles n1&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CROSS&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;JOIN&lt;/SPAN&gt; #Nybbles n2&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CROSS&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;JOIN&lt;/SPAN&gt; #Nybbles n3&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CROSS&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;JOIN&lt;/SPAN&gt; #Nybbles n4&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;INSERT&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;INTO&lt;/SPAN&gt; BitPattern&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Num&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Trailing&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Leading&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Seq&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;SELECT&lt;/SPAN&gt; g&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&lt;/SPAN&gt; &lt;SPAN style="COLOR:fuchsia;"&gt;MAX&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;b1&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;Length&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt;&amp;nbsp;&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM&lt;/SPAN&gt; #BitMask b1&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHERE&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;RIGHT(&lt;/SPAN&gt;g&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;String&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; b1&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;Length&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;=&lt;/SPAN&gt; b1&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Mask&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; Trailing&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&lt;/SPAN&gt; &lt;SPAN style="COLOR:fuchsia;"&gt;MAX&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;b2&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;Length&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt;&amp;nbsp;&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM&lt;/SPAN&gt; #BitMask b2&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHERE&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;LEFT(&lt;/SPAN&gt;g&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;String&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; b2&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;Length&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;=&lt;/SPAN&gt; b2&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Mask&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; Leading&lt;SPAN style="COLOR:gray;"&gt;,&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:fuchsia;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; COALESCE&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT&lt;/SPAN&gt; &lt;SPAN style="COLOR:fuchsia;"&gt;MAX&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;b3&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;Length&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM&lt;/SPAN&gt; #BitMask b3&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHERE&lt;/SPAN&gt; &lt;SPAN style="COLOR:fuchsia;"&gt;CHARINDEX&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;b3&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Mask&lt;SPAN style="COLOR:gray;"&gt;,&lt;/SPAN&gt; g&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;String&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;&amp;gt;&lt;/SPAN&gt; 0&lt;BR&gt;&lt;SPAN style="COLOR:gray;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ),&lt;/SPAN&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; Seq&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;FROM&lt;/SPAN&gt; GetBin g&lt;BR&gt;&lt;SPAN style="COLOR:blue;"&gt;ORDER&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;BY&lt;/SPAN&gt; Num&lt;SPAN style="COLOR:gray;"&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;GO&lt;BR&gt;&lt;BR&gt;DROP&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;TABLE&lt;/SPAN&gt; #BitMask&lt;SPAN style="COLOR:gray;"&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;DROP&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;TABLE&lt;/SPAN&gt; #Nybbles&lt;SPAN style="COLOR:gray;"&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;GO&lt;/SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;The first part of this script puts all 16 combinations of 4-bit nybbles (nybble = half a byte) and their equivalent binary formatted strings (0 = '0000', 14 = '1110') into a temp table called #Nybbles.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;There’s also a #BitMask temp table with bitmasks representing zero-bit runs.&amp;nbsp; The bitmasks are just strings of consecutive '0' characters of the necessary length (length 1 = '0', length 5 = '00000').&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;The BitPatterns table is the actual 16-bit number lookup table.&amp;nbsp; This table is populated by combining every 16-bit combination of nybbles from the #Nybbles temp table.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;This table has 4 columns:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV style="TEXT-INDENT:-0.25in;MARGIN-LEFT:38pt;mso-list:l1 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;Num is the 16-bit number&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV style="TEXT-INDENT:-0.25in;MARGIN-LEFT:38pt;mso-list:l1 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;Trailing is the number of zero bits trailing (on the right-hand side) in the number&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV style="TEXT-INDENT:-0.25in;MARGIN-LEFT:38pt;mso-list:l1 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;Leading is the number of zero bits leading (on the left-hand side) in the number&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV style="TEXT-INDENT:-0.25in;MARGIN-LEFT:38pt;mso-list:l1 level1 lfo1;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;Seq is the longest sequence of zero bits within the number&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P style="MARGIN-LEFT:2pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN-LEFT:2pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;The total run time to build this lookup table was around 30 seconds on my computer.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;Keep in mind that’s a one-time cost since you never have to build (or modify) the table again.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT:2pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN-LEFT:2pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;With the information in this lookup table the query that locates the longest run of zero bits in any given 32-bit number is relatively simple:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT:2pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;FONT size=3&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;DBCC&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt; FREEPROCCACHE&lt;SPAN style="COLOR:gray;"&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;FONT size=3&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;DBCC&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt; DROPCLEANBUFFERS&lt;SPAN style="COLOR:gray;"&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;&lt;FONT size=3&gt;GO&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;&lt;o:p&gt;&lt;FONT size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;FONT size=3&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;WITH&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt; CTE&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;&lt;FONT size=3&gt;AS&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:gray;"&gt;&lt;FONT size=3&gt;(&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;SELECT&lt;/SPAN&gt; tn&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num&lt;SPAN style="COLOR:gray;"&gt;,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;FONT size=3&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:gray;"&gt;(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;SELECT&lt;/SPAN&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;CASE&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;WHEN&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Seq &lt;SPAN style="COLOR:gray;"&gt;&amp;gt;&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Seq &lt;SPAN style="COLOR:blue;"&gt;THEN&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;FONT size=3&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:gray;"&gt;(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;CASE&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;WHEN&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Seq &lt;SPAN style="COLOR:gray;"&gt;&amp;gt;&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Trailing &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Leading &lt;SPAN style="COLOR:blue;"&gt;THEN&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Seq &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;ELSE&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Trailing &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Leading &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;END&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;ELSE&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;FONT size=3&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:gray;"&gt;(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;CASE&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;WHEN&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Seq &lt;SPAN style="COLOR:gray;"&gt;&amp;gt;&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Trailing &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Leading &lt;SPAN style="COLOR:blue;"&gt;THEN&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Seq &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;ELSE&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Trailing &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Leading &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;END&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;END&lt;/SPAN&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; Seq&lt;SPAN style="COLOR:gray;"&gt;,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;CASE&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;WHEN&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Trailing &lt;SPAN style="COLOR:gray;"&gt;=&lt;/SPAN&gt; 16 &lt;SPAN style="COLOR:blue;"&gt;THEN&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Trailing &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Trailing&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;ELSE&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Trailing&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;END&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; Trailing&lt;SPAN style="COLOR:gray;"&gt;,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;CASE&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;WHEN&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Leading &lt;SPAN style="COLOR:gray;"&gt;=&lt;/SPAN&gt; 16 &lt;SPAN style="COLOR:blue;"&gt;THEN&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Leading &lt;SPAN style="COLOR:gray;"&gt;+&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Leading&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;ELSE&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Leading&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;END&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;AS&lt;/SPAN&gt; Leading&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;FROM&lt;/SPAN&gt; TempNum tn &lt;SPAN style="COLOR:blue;"&gt;WITH &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;NOLOCK&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;INNER&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;JOIN&lt;/SPAN&gt; BitPattern l &lt;SPAN style="COLOR:blue;"&gt;WITH &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;NOLOCK&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;ON&lt;/SPAN&gt; l&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:gray;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;tn&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:gray;"&gt;&amp;amp;&lt;/SPAN&gt; 65535&lt;SPAN style="COLOR:gray;"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;INNER&lt;/SPAN&gt; &lt;SPAN style="COLOR:gray;"&gt;JOIN&lt;/SPAN&gt; BitPattern h &lt;SPAN style="COLOR:blue;"&gt;WITH &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;NOLOCK&lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;ON&lt;/SPAN&gt; h&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:gray;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:gray;"&gt;(&lt;/SPAN&gt;tn&lt;SPAN style="COLOR:gray;"&gt;.&lt;/SPAN&gt;Num &lt;SPAN style="COLOR:gray;"&gt;/&lt;/SPAN&gt; 65536&lt;SPAN style="COLOR:gray;"&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:gray;"&gt;&lt;FONT size=3&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;FONT size=3&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;SELECT&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt; Num&lt;SPAN style="COLOR:gray;"&gt;,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Seq&lt;SPAN style="COLOR:gray;"&gt;,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Leading&lt;SPAN style="COLOR:gray;"&gt;,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt;&lt;FONT size=3&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Trailing&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;FONT size=3&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;INTO&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt; #Temp&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;FONT size=3&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;FROM&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';"&gt; CTE&lt;SPAN style="COLOR:gray;"&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;&lt;FONT size=3&gt;GO&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT:normal;MARGIN:0in 0in 0pt 2pt;mso-layout-grid-align:none;" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY:'Courier New';COLOR:blue;"&gt;&lt;FONT size=3&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN-LEFT:2pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;Basically you join the BitPattern lookup table on the high 16 bits and again on the low 16 bits.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;The first CASE expression in the Seq subquery performs a 3-way maximum calculation.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;It returns the largest of:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT:2pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV style="MARGIN-LEFT:2pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;the low word zero-bit run (l.Seq),&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV style="MARGIN-LEFT:2pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;the high word zero-bit run (h.Seq), or&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV style="MARGIN-LEFT:2pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;the count of high word trailing zero-bits + the count of low word leading zero-bits (h.Trailing + l.Leading)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P style="MARGIN-LEFT:4.65pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN-LEFT:4.65pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;The other two CASE expressions return the total number of trailing and leading zero-bits in the 32-bit number.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;The CASE expression is needed to handle the case when the high or low word is all zero-bits.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT:4.65pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN-LEFT:4.65pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;This particular solution took an average of about 6 seconds to calculate the longest zero-bit run for 1,000,000 numbers.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT:4.65pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN-LEFT:4.65pt;"&gt;&lt;SPAN style="FONT-FAMILY:'Arial','sans-serif';FONT-SIZE:11pt;"&gt;To my earlier point, I created a C# solution (which itself could have been optimized) that performed the exact same calculation for 1,000,000 random 32 bit integers in 2 seconds flat.&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;So I guess there are two main points here: (1) Make sure you choose the right tool/language for the job, and (2) Whatever tool/language you choose try to play to its strengths.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;</description></item><item><title>Calculating Holidays in SQL</title><link>http://sqlblog.com/blogs/michael_coles/archive/2010/02/25/calculating-holidays-in-sql.aspx</link><pubDate>Thu, 25 Feb 2010 21:51:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:22626</guid><dc:creator>Mike C</dc:creator><description>&lt;P&gt;Ask about&amp;nbsp;nearly any kind of SQL-based date calculation in the &lt;A title="SQL Public Newsgroup" href="http://groups.google.com/group/microsoft.public.sqlserver.programming/topics?hl=en"&gt;newsgroups&lt;/A&gt;, and you'll likely get responses that include use of an &lt;A title="Auxiliary Calendar Table @ ASPFAQ" href="http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html"&gt;auxiliary calendar table&lt;/A&gt;.&amp;nbsp; It's a really good idea, and something I highly recommend to anyone who has to do date-based calculations on the server.&amp;nbsp; For those who do dimensional modeling, you'll probably notice the auxiliary calendar table closely resembles a Time dimension with one-day intervals.&amp;nbsp; I won't get into too much detail on it, since ASPFAQ and the newsgroups cover it well.&lt;/P&gt;
&lt;P&gt;What I do want to talk about is calculating holidays, which can be important when populating your auxiliary calendar table.&amp;nbsp; When you create an auxiliary calendar table you may need to perform calculations based on business days, for instance; or you may need to schedule activities before, after, or even during certain holidays.&amp;nbsp; There are two types of holidays that I'll address:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Fixed holidays that fall on the same day every year&lt;/LI&gt;
&lt;LI&gt;Floating holidays for which the date can change from year to year&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Fixed holidays include holidays that always fall on the same day each year.&amp;nbsp; Some examples of fixed holidays include &lt;A title="Merry Christmas!" href="http://en.wikipedia.org/wiki/Christmas"&gt;Christmas&lt;/A&gt; (always December 25 in the West), &lt;A title="Oh, Canada!" href="http://en.wikipedia.org/wiki/Canada_Day"&gt;Canada Day&lt;/A&gt; (always July 1), &lt;A title="July 4th!" href="http://en.wikipedia.org/wiki/Independence_Day_(United_States)"&gt;U.S. Independence Day&lt;/A&gt; (always July 4).&amp;nbsp; These are fairly easy to detect and set in your auxiliary calendar table.&amp;nbsp; Just look for the static month + day combinations in your table and update it accordingly.&lt;/P&gt;
&lt;P&gt;Floating holidays are far more interesting and difficult to calculate.&amp;nbsp; Take Easter.&amp;nbsp; Easter actually has two definitions.&amp;nbsp; The popular definition is:&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;"Easter Day is the first Sunday after the full moon that occurs next after the vernal equinox"&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This&amp;nbsp;is not the exact ecclesiastical definition though.&amp;nbsp; The full moon here is not the astronomical full moon but an "ecclesiastical moon" that's determined&amp;nbsp;through precalculated lookup tables.&amp;nbsp; The ecclesiastical rules are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Easter falls on the first Sunday following the first ecclesiastical full moon that occurs on or after the day of the vernal equinox&lt;/LI&gt;
&lt;LI&gt;This particular ecclesiastical full moon is the 14th day of a tabular lunation (new moon)&lt;/LI&gt;
&lt;LI&gt;The vernal equinox is fixed as March 21&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I'm not going to recount the long and painful history leading to the modern definition of Easter--but the details&amp;nbsp;can be found on &lt;A title="Easter Controversy" href="http://en.wikipedia.org/wiki/Easter_controversy"&gt;Wikipedia&lt;/A&gt;&amp;nbsp;if you're interested.&amp;nbsp; The main point is that Easter calculation is fairly complex.&amp;nbsp; The udf_CalculateEaster function below accepts the year (integer) as a parameter and returns the date of Easter for that year (datetime).&amp;nbsp; Notice the large number of calculations required to make this function work:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;CREATE FUNCTION dbo.udf_CalculateEaster &lt;BR&gt;(&lt;BR&gt;&lt;/STRONG&gt;&lt;STRONG&gt;&amp;nbsp; @Year INT&lt;BR&gt;)&lt;BR&gt;RETURNS DATETIME&lt;BR&gt;AS&lt;BR&gt;BEGIN&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DECLARE @Date DATETIME,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @c INT, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @n INT, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @i INT, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @k INT, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @j INT, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @l INT, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @m INT, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @d INT;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SELECT @n = @Year - 19 * (@Year / 19),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @c = @Year / 100,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @k = (@c - 17) / 25,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @i = @c - @c / 4 - (@c - @k) / 3 + 19 * @n + 15,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @i = @i - 30 * (@i / 30),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @i = @i - (@i / 28) * (1 - (@i / 28) * (29 / (@i + 1)) * ((21 - @n) / 11)),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @j = @Year + @Year / 4 + @i + 2 - @c + @c / 4,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @j = @j - 7 * (@j / 7),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @l = @i - @j,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @m = 3 + (@l + 40) / 44,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @d = @l + 28 - 31 * (@m / 4),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Date = CAST&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CAST(@Year AS CHAR(4)) + &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RIGHT&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; '0' + CAST&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @m AS VARCHAR(2)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ), 2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) + &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RIGHT&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; '0' +CAST&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @d AS VARCHAR(2)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ), 2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) AS DATETIME&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RETURN @Date;&lt;BR&gt;END;&lt;BR&gt;GO&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;If you want the date for Easter 2010, just run a query like the following:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;SELECT dbo.udf_CalculateEaster (2010);&lt;BR&gt;GO&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The result is &lt;EM&gt;2010-04-04&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;Another somewhat daunting type of floating holiday is the type that is based on the Nth weekday of the month. These holidays are defined using terms like "the 4th Thursday of November" (&lt;A title="Turkey Day!" href="http://en.wikipedia.org/wiki/Thanksgiving"&gt;U.S. Thanksgiving&lt;/A&gt;), "the&amp;nbsp;3rd&amp;nbsp;Monday in January" (&lt;A title="MLK Day!" href="http://en.wikipedia.org/wiki/Martin_Luther_King_Day"&gt;U.S. Martin Luther King Day&lt;/A&gt;), or even "the *last* Monday in May" (&lt;A title='Formerly "Decoration Day"' href="http://en.wikipedia.org/wiki/Memorial_day"&gt;U.S. Memorial Day&lt;/A&gt;). These floating holidays are not as hard to calculate as Easter, but still a little tricky (particularly Memorial Day).&lt;/P&gt;
&lt;P&gt;To calculate these dates we need a function like udf_nthWeekDay below. This function accepts 4 parameters:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV&gt;@n = integer that represents which instance of the weekday you're looking for.&amp;nbsp; This would be the 4 in "4th Thursday&amp;nbsp;in November".&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;@weekDay = 3-character day of week ("SUN" = Sunday, "MON" = Monday, etc.)&amp;nbsp; I used character abbreviations instead of numbers just to make it a little easier.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;@year = integer year for which to calculate&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;@month = integer month for which to calculate (1 = January, 2 = February, etc.)&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;As you can see below, the Nth weekday calculation is pretty simple.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;CREATE FUNCTION dbo.udf_nthWeekDay&lt;BR&gt;(&lt;BR&gt;&amp;nbsp; @n&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT, &lt;BR&gt;&amp;nbsp; @weekDay CHAR(3),&lt;BR&gt;&amp;nbsp; @year&amp;nbsp;&amp;nbsp;&amp;nbsp; INT, &lt;BR&gt;&amp;nbsp; @month&amp;nbsp;&amp;nbsp; INT&lt;BR&gt;)&lt;BR&gt;RETURNS DATETIME&lt;BR&gt;AS&lt;BR&gt;BEGIN&lt;BR&gt;&amp;nbsp; DECLARE @date&amp;nbsp;&amp;nbsp;&amp;nbsp; DATETIME,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @dow&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @offset&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @wd&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INT;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp; SELECT @wd = CASE @weekDay&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHEN 'SUN' THEN 1&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHEN 'MON' THEN 2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHEN 'TUE' THEN 3&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHEN 'WED' THEN 4&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHEN 'THU' THEN 5&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHEN 'FRI' THEN 6&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHEN 'SAT' THEN 7&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; END,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @date = CAST&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CAST(@year AS VARCHAR(4)) +&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RIGHT&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; '0' + CAST&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @month AS VARCHAR(2)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ), 2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) +&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; '01' AS DATETIME&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @dow = DATEPART(dw, @date),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @offset = @wd - @dow,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @date = DATEADD(day, @offset + (@n - CASE WHEN @offset &amp;gt;= 0 THEN 1 ELSE 0 END) * 7, @date);&lt;BR&gt;&amp;nbsp; RETURN @date;&lt;BR&gt;END;&lt;BR&gt;GO&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;To get the date for Thanksgiving 2024 you could call the function like this:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;SELECT dbo.udf_nthWeekDay&lt;BR&gt;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'THU',&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2024, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 11&lt;BR&gt;&amp;nbsp; );&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The result is &lt;EM&gt;2024-11-28&lt;/EM&gt;.&amp;nbsp; Now for a holiday like U.S. Memorial Day ("the last Monday in May") the calculation is a little trickier.&amp;nbsp; You have no idea up front how many Mondays there are in any given May.&amp;nbsp; As an example, in 2010 and 2011 there are 5 Mondays in May; in 2012 and 2013 there are only 4.&amp;nbsp; You could try to figure out the number of Mondays in May of the given year, but that's way too much work.&lt;/P&gt;
&lt;P&gt;There's one thing we know about the last Monday in May with absolute certainty:&amp;nbsp; after the last Monday in May, the next Monday we encounter will *always* be the first Monday in June.&amp;nbsp; So the easier way to figure out the last Monday in May is to calculate the first Monday in June and then back into it (subtract 7 days), like this:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;SELECT DATEADD&lt;BR&gt;(&lt;BR&gt;&amp;nbsp; day, &lt;BR&gt;&amp;nbsp; -7,&lt;BR&gt;&amp;nbsp; dbo.udf_nthWeekDay&lt;BR&gt;&amp;nbsp; (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'MON',&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2012, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&lt;BR&gt;&amp;nbsp; )&lt;BR&gt;);&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;By calculating the date of the first Monday in June 2012, we can then subtract 7 days to get the date of the last Monday of May: &lt;EM&gt;2012-05-28&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;You can use the functions to calculate holidays for your auxiliary calendar table.&amp;nbsp; I covered U.S. federal (and some other national) holidays in this one, but it can be extended to cover other national, state, and local holidays.&lt;/P&gt;</description></item><item><title>Service Packs... Coming to a Download Near You!</title><link>http://sqlblog.com/blogs/michael_coles/archive/2010/02/14/service-packs-coming-to-a-download-near-you.aspx</link><pubDate>Sun, 14 Feb 2010 23:07:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:22289</guid><dc:creator>Mike C</dc:creator><description>&lt;P&gt;Based on feedback from the community (&lt;A href="https://connect.microsoft.com/SQLServer/feedback/details/522123/sql-server-2008-service-pack-2"&gt;https://connect.microsoft.com/SQLServer/feedback/details/522123/sql-server-2008-service-pack-2&lt;/A&gt;&amp;nbsp;and &lt;A href="https://connect.microsoft.com/SQLServer/feedback/details/522122/service-pack-4-for-sql-server-2005"&gt;https://connect.microsoft.com/SQLServer/feedback/details/522122/service-pack-4-for-sql-server-2005&lt;/A&gt;), Microsoft has announced plans to release Service Pack 2 for SQL Server 2008 and Service Pack 4 for SQL Server 2005. The official announcement from the SQL Server Group Project Manager Matthias&amp;nbsp;Berndt is &lt;A title="Service Pack Announcement" href="http://blogs.msdn.com/sqlreleaseservices/archive/2010/02/12/sql-server-servicing-plans.aspx" target=_blank&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Here's the abbreviated version:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Service Pack 2 for SQL Server 2008 is targeted for a Q3 release.&lt;/LI&gt;
&lt;LI&gt;Service Pack 4 for SQL Server 2005 is targeted for a Q4 release.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;SP 4 is currently scheduled to be the final SP for 2005. The announcement also contains some info. about SQL 2005 going into extended support from April 2011 to April 2016.&lt;/P&gt;</description></item><item><title>Almost T-SQL Tuesday #003: Calculating Products - An Oldie But Goodie</title><link>http://sqlblog.com/blogs/michael_coles/archive/2010/02/10/almost-t-sql-tuesday-003.aspx</link><pubDate>Wed, 10 Feb 2010 05:11:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:22090</guid><dc:creator>Mike C</dc:creator><description>&lt;P&gt;Looks like I just missed the deadline for &lt;A href="http://msmvps.com/blogs/robfarley/archive/2010/02/02/invitation-for-t-sql-tuesday-003-relationships.aspx"&gt;T-SQL Tuesday #003&lt;/A&gt; [oh well, whatcha gonna do].&amp;nbsp; The other day someone asked me about an oldie but goodie that hits on a math-based relationship. SQL Server has several aggregate functions like SUM for summation.&amp;nbsp;&lt;A title="Sum - Sigma notation - Wikipedia" href="http://en.wikipedia.org/wiki/Sum"&gt;Summation&lt;/A&gt; is the addition of a set of numbers, and it's represented with&amp;nbsp;sigma notation, like this:&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:390px;HEIGHT:47px;" title="Sigma notation from Wikipedia" alt="Sigma notation from Wikipedia" src="http://upload.wikimedia.org/math/a/f/c/afc2cecd80733380cfad8409f68d202e.png" width=390 height=47&gt;&lt;/P&gt;
&lt;P&gt;The question was how do you calculate a product in SQL?&amp;nbsp; Keep in mind that SQL has no built-in PRODUCT aggregate.&amp;nbsp;A &lt;A title="Product - Capital PI Notation - Wikipedia" href="http://en.wikipedia.org/wiki/Multiplication#Capital_pi_notation"&gt;product&lt;/A&gt; is the multiplication of a series of numbers, and is represented with capital PI notation:&lt;/P&gt;
&lt;P&gt;&lt;IMG style="WIDTH:356px;HEIGHT:47px;" title="Capital PI notation" alt="Capital PI notation" src="http://upload.wikimedia.org/math/d/e/e/dee32298e872094bf3fe2d7becd76ef4.png" width=356 height=47&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The question was how do you perform a&amp;nbsp;product aggregation in SQL? The most obvious way to solve the problem is with a simple cursor or loop.&amp;nbsp;You could also create a SQL CLR UDF. But we can solve it even simpler than that, in pure SQL.&amp;nbsp;So how do we solve it with a SQL set-based solution?&lt;/P&gt;
&lt;P&gt;Well, mathematics provides us a relationship between&amp;nbsp;&lt;A href="http://en.wikipedia.org/wiki/Logarithm#Exponential_functions"&gt;logarithms&lt;/A&gt; and exponents that allows us to turn a product into a simple summation. The code below demonstrates.&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;CREATE&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;TABLE&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Tab&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;val &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;float&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;GO&lt;BR&gt;&lt;BR&gt;INSERT&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;INTO&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Tab&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;val&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;VALUES &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;9.3&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;),&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;4.5&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;),&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;2.6&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;),&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;11.4&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;),&lt;BR&gt;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;3&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;GO&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;SELECT&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;&lt;FONT color=#ff00ff size=2&gt;EXP&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;&lt;FONT color=#ff00ff size=2&gt;SUM&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff00ff size=2&gt;&lt;FONT color=#ff00ff size=2&gt;LOG&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;val&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)))&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;AS&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT size=2&gt;&lt;STRONG&gt; product&lt;/STRONG&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Tab&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;GO&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;The sample sums the natural logarithms of val, and then returns the exponential of that sum.&amp;nbsp;The end result is the product of the values in the val column. One thing to watch out for is that this method will error out if any of the values are &amp;lt;= 0.&amp;nbsp;You can accomodate for this issue with a CASE expression, but that's for another day.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;WHO DAT?&lt;/P&gt;</description></item></channel></rss>