<?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 'T-SQL Tuesday' and 'time'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=T-SQL+Tuesday,time&amp;orTags=0</link><description>Search results matching tags 'T-SQL Tuesday' and 'time'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>T-SQL Tuesday #001: Exploring &amp;quot;Fuzzy&amp;quot; Interval Islands Using SQLCLR</title><link>http://sqlblog.com/blogs/adam_machanic/archive/2009/12/08/t-sql-tuesday-001-exploring-fuzzy-interval-islands-using-sqlclr.aspx</link><pubDate>Tue, 08 Dec 2009 19:13:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:19621</guid><dc:creator>Adam Machanic</dc:creator><description>&lt;p&gt;When working with time intervals, we often want to ask a couple of basic questions: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which time periods are not covered by our intervals? These are known as "gaps".&lt;/li&gt;

&lt;li&gt;What are the time ranges that we are fully covering? These are known as "islands".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're unfamiliar with "gaps" and "islands" I highly recommend reading some of Itzik Ben-Gan's recent work in SQL Server Magazine. He's had a great series going on the topic. But one thing that he hasn't found a good T-SQL solution for is a problem that I call "fuzzy islands." &lt;/p&gt;

&lt;p&gt;&lt;b&gt;When is an island fuzzy?&lt;/b&gt; When it doesn't necessarily have a fixed end time. For an example of this, consider a store, selling a number of products. Management might want to see a report showing when each product was selling. This is, effectively, an island question. The goal is to find all of the covered ranges during which sales occurred. But running such a report, you might find that way too much data is returned. A given product may have sold units on Monday, Tuesday, and Thursday, but for some reason no one bought one on Wednesday. Creating a new island every time there is a small gap will create a 300-page report where a 1-page dashboard might suffice--not a good user experience, nor a good way of representing the data. The solution? Introduce a bit of fuzziness--a rule that says, for instance, that a gap is only a gap if it's longer than 7 days.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Answering the fuzzy islands question &lt;/b&gt;is not a very difficult thing to do in T-SQL. The basic algorithm follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find all of the "start" dates or times. These are simply those dates or times for which a previous date or time in the fuzzy interval does not exist. So if a row is dated 2009-12-08 and our fuzzy granularity is 7 days, we know we have a start date if there is no other covered data from the end of November.&lt;/li&gt;

&lt;li&gt;For each start date identified, find the minimum date greater than the start date. This is done by looking ahead rather than behind, so if our date is 2009-12-08 and we have a granularity of 7 days, we'll look forward until December 15th.&lt;/li&gt;

&lt;li&gt;Optionally, add the fuzzy factor to the end date. This is something that I think is a good idea, as it introduces the concept of an "active" interval--a period over which, for example, a product is considered to have been selling. The interval shouldn't necessarily terminate the day that the last sale occurred. But of course this depends on the situation in question.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The following query produces a fuzzy islands report for each product in the AdventureWorks (or AdventureWorks2008) Production.TransactionHistory table. You can modify the @active_interval variable to tweak the fuzziness and change the output. &lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;
&lt;pre&gt;--Find all "active" product time ranges, meaning that the product&lt;br&gt;--has sold within the previous 7 days&lt;br&gt;DECLARE @active_interval INT = 7&lt;br&gt;&lt;br&gt;SELECT DISTINCT&lt;br&gt;    t_s.ProductID,&lt;br&gt;    t_s.TransactionDate AS StartDate,&lt;br&gt;    DATEADD&lt;br&gt;    (&lt;br&gt;        dd,&lt;br&gt;        @active_interval,&lt;br&gt;        (&lt;br&gt;            SELECT&lt;br&gt;                MIN(t_e.TransactionDate)&lt;br&gt;            FROM Production.TransactionHistory AS t_e&lt;br&gt;            WHERE&lt;br&gt;                t_e.ProductID = t_s.ProductID&lt;br&gt;                AND t_e.TransactionDate &amp;gt;= t_s.TransactionDate&lt;br&gt;                AND NOT EXISTS&lt;br&gt;                (&lt;br&gt;                    SELECT *&lt;br&gt;                    FROM Production.TransactionHistory AS t_ae&lt;br&gt;                    WHERE&lt;br&gt;                        t_ae.ProductID = t_s.ProductID&lt;br&gt;                        AND t_ae.TransactionDate BETWEEN &lt;br&gt;                            DATEADD(dd, 1, t_e.TransactionDate) &lt;br&gt;                            AND DATEADD(dd, @active_interval, t_e.TransactionDate)&lt;br&gt;                )&lt;br&gt;        )&lt;br&gt;    ) AS EndDate&lt;br&gt;FROM &lt;br&gt;(&lt;br&gt;    SELECT DISTINCT&lt;br&gt;        ProductID,&lt;br&gt;        TransactionDate&lt;br&gt;    FROM Production.TransactionHistory&lt;br&gt;) AS t_s&lt;br&gt;WHERE&lt;br&gt;    NOT EXISTS&lt;br&gt;    (&lt;br&gt;        SELECT *&lt;br&gt;        FROM Production.TransactionHistory AS t_ps&lt;br&gt;        WHERE&lt;br&gt;            t_ps.ProductID = t_s.ProductID&lt;br&gt;            AND t_ps.TransactionDate BETWEEN &lt;br&gt;                DATEADD(dd, -@active_interval, t_s.TransactionDate) &lt;br&gt;                AND DATEADD(dd, -1, t_s.TransactionDate)&lt;br&gt;    )&lt;br&gt;ORDER BY&lt;br&gt;    ProductID,&lt;br&gt;    StartDate&lt;br&gt;GO&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Running this query you'll find that it works... But the results are returned a bit more slowly than we might desire--15 to 16 seconds on my end. Looking at the query plan, the reason for this becomes quite obvious: Lots and lots of table scans. How can we eliminate all of the overhead?&lt;/p&gt;
&lt;p&gt;&lt;b&gt;SQLCLR to the rescue.&lt;/b&gt; The best way to solve this problem--at least until the SQL Server team adds proper OVER clause support (LAG and LEAD, specifically)--is to use a cursor algorithm. We could do this in a T-SQL cursor, but why bother? Cursor logic in SQLCLR is much, much faster. &lt;/p&gt;
&lt;p&gt;To solve the problem, I implemented an enumerator, called active_products_enumerator. The enumerator is initialized using a SqlDataReader and an "active interval" -- the number of days we're allowing for fuzziness. The DataReader is expected to return rows ordered by ProductID and TransactionDate. The enumeration process uses the following algorithm:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If the current ProductID is not the same as the previous ProductID, return an end date for the previous interval and start a new one&lt;/li&gt;
&lt;li&gt;If the current period date is greater than the previous period date plus the active interval, return an end date for the previous interval and start a new one&lt;/li&gt;
&lt;li&gt;Otherwise, continue&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Following is the MoveNext method for the enumerator (the complete code is attached to this post so that you can run it on your end without my bombarding you with a gigantic code-filled post):&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;p&gt;public bool MoveNext()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&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; current_results = null;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (r.Read())&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;&amp;nbsp;&amp;nbsp; new_ProductID = r.GetSqlInt32(0);&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; new_period_date = r.GetDateTime(1);&lt;br&gt;&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; if (new_ProductID != ProductID)&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; {&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; if (ProductID != 0)&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; {&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;&amp;nbsp;&amp;nbsp; current_results = new results(&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProductID,&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StartDate,&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; period_plus_interval);&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; }&lt;br&gt;&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; ProductID = new_ProductID;&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; StartDate = new_period_date;&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; period_plus_interval = new_period_date.AddDays(activeInterval);&lt;br&gt;&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; if (current_results != null)&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;&amp;nbsp;&amp;nbsp; return (true);&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; }&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&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; {&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; if (period_plus_interval &amp;lt; new_period_date)&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; {&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;&amp;nbsp;&amp;nbsp; current_results = new results(&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProductID,&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StartDate,&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; period_plus_interval);&lt;br&gt;&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;&amp;nbsp;&amp;nbsp; StartDate = new_period_date;&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; }&lt;br&gt;&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; period_plus_interval = new_period_date.AddDays(activeInterval);&lt;br&gt;&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; if (current_results != null)&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;&amp;nbsp;&amp;nbsp; return (true);&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; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //return the last row of data&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ProductID != 0)&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;&amp;nbsp;&amp;nbsp; current_results = new results(&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; ProductID,&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; StartDate,&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; period_plus_interval);&lt;br&gt;&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; //set this to 0 so we don't return another row&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; ProductID = 0;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (current_results != null)&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; return (true);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&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;&amp;nbsp;&amp;nbsp; r.Dispose();&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; return (false);&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; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch&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; r.Dispose();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;/p&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Put into a table-valued function, as the attached code does, this algorithm will return the same data as the T-SQL query in under a third of a second on my end--&lt;span style="font-weight:bold;"&gt;around 45 times faster than the T-SQL version&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;Note that I've played some games with a loopback connection to get this whole thing to work. That's a topic for a future blog post, so stay tuned. In the meantime, please realize that you'll have to catalog the assembly with EXTERNAL_ACCESS permission to make this happen.&lt;/p&gt;&lt;p&gt;This post was created for T-SQL Tuesday, the revolving SQL Server blog party, hosted this month by... &lt;a href="http://sqlblog.com/blogs/adam_machanic/archive/2009/11/30/invitation-to-participate-in-t-sql-tuesday-001-date-time-tricks.aspx"&gt;me&lt;/a&gt;. Enjoy! &lt;br&gt;&lt;/p&gt;</description></item><item><title>Invitation to Participate in T-SQL Tuesday #001: Date/Time Tricks</title><link>http://sqlblog.com/blogs/adam_machanic/archive/2009/11/30/invitation-to-participate-in-t-sql-tuesday-001-date-time-tricks.aspx</link><pubDate>Mon, 30 Nov 2009 17:47:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:19338</guid><dc:creator>Adam Machanic</dc:creator><description>&lt;p&gt;T-SQL Tuesday is the SQL Server blogosphere's first &lt;b&gt;recurring, revolving blog party&lt;/b&gt;.
The idea is simple: Each month a blog will host the party, and about a
week before the second Tuesday of the month a theme will be posted. Any
blogger that wishes to participate is invited to write a post on the
chosen topic. The event is called "T-SQL Tuesday", but &lt;b&gt;any post that is related to both SQL Server and the theme is fair game&lt;/b&gt;.
So feel free to post about SSIS, SSRS, Java integration, or whatever
other technologies you're working with in conjunction with SQL Server.
Even if your post includes no T-SQL we still want to see it. &lt;/p&gt;&lt;p&gt;The
posts must go live on the second Tuesday of the month, by (or before)
23:59 PST. Each post must link back to the host blog's post, and the
blogger should make sure that a trackback has been generated and
successfully posted to the host blog; if not, a comment should be
posted on the host blog with a link, so that the host blogger can find
the post. The host blogger will then take all of the posts and
within a day or two will compile a "roundup"--a brief summary with links--so
that readers can find all of the relevant posts.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Why do this?&lt;/b&gt;
Several reasons: It's fun, it's going to generate a lot of interesting
content, and it's going to bring lots of bloggers into the fold and
improve our overall community by creating a lot of links between
blogs. Any blogger is invited to participate, whether the blog has been
live for six days or six years. If you can write, you should join in
the fun.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Rules of engagement for hosts&lt;/b&gt;: Although anyone
can join in the party, hosting has a slightly higher bar: Your blog
must have been active in the last six months ("active" is defined as at
least one post per month), and you must have participated in T-SQL
Tuesday events on at least two prior occasions. Since that's impossible
until we've had two events, I'll host the first two myself. After that
it will move around to as many blogs as we can get involved--and I hope
that a number of you out there decide to go for it. The host blogger is not required to write a participating post to be included in
the roundup, but is free to do so if he or she chooses. &lt;b&gt;Want to host?&lt;/b&gt; Contact me through my blog--I'll
keep a waiting list and control it centrally so that it doesn't devolve
into anarchy too quickly.&lt;/p&gt;&lt;p&gt;So that's that. If you bothered to read the title of this post you're aware that &lt;b&gt;the topic for this month is Date/Time Tricks&lt;/b&gt;.
Write a blog post that talks about dates and times--this can be based
around T-SQL programming, data modeling, ETL, reporting, or whatever
else you're using dates and times for (and who isn't?). Make sure that
your post goes live on &lt;b&gt;Tuesday, December 8, between 00:00 and 23:59 PST&lt;/b&gt;. Make it clear in your post that it's for T-SQL Tuesday, and make sure it links back here. Finally, &lt;b&gt;make absolutely certain that a comment shows up here&lt;/b&gt; so that I can find the post.&lt;/p&gt;&lt;p&gt;Questions? Comments? Post here.&lt;/p&gt;&lt;p&gt;Enjoy! I'm looking forward to the start of a great blog tradition in the SQL Server community.&lt;br&gt;&lt;/p&gt;</description></item></channel></rss>