<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www2.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>Adam Machanic : puzzle</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/puzzle/default.aspx</link><description>Tags: puzzle</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>T-SQL Tuesday #002: The Roundup</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2010/02/08/t-sql-tuesday-002-the-roundup.aspx</link><pubDate>Mon, 08 Feb 2010 19:14:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:21860</guid><dc:creator>Adam Machanic</dc:creator><slash:comments>3</slash:comments><comments>http://www2.sqlblog.com/blogs/adam_machanic/comments/21860.aspx</comments><wfw:commentRss>http://www2.sqlblog.com/blogs/adam_machanic/commentrss.aspx?PostID=21860</wfw:commentRss><description>According to T-SQL Tuesday rules as ratified by me in the first and second T-SQL Tuesday posts, the T-SQL Tuesday host is supposed to post a roundup within two days of the end of the event. So a reasonable person should expect a roundup to be posted by...(&lt;a href="http://www2.sqlblog.com/blogs/adam_machanic/archive/2010/02/08/t-sql-tuesday-002-the-roundup.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www2.sqlblog.com/aggbug.aspx?PostID=21860" width="1" height="1"&gt;</description><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/puzzle/default.aspx">puzzle</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/T-SQL+Tuesday/default.aspx">T-SQL Tuesday</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/_2300_tsql2sday/default.aspx">#tsql2sday</category></item><item><title>T-SQL Tuesday #002: Is it XML, or Not?!?</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2010/01/12/t-sql-tuesday-002-is-it-xml-or-not.aspx</link><pubDate>Tue, 12 Jan 2010 21:19:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:20965</guid><dc:creator>Adam Machanic</dc:creator><slash:comments>8</slash:comments><comments>http://www2.sqlblog.com/blogs/adam_machanic/comments/20965.aspx</comments><wfw:commentRss>http://www2.sqlblog.com/blogs/adam_machanic/commentrss.aspx?PostID=20965</wfw:commentRss><description>The query optimizer is a finicky thing , and sometimes it doesn't understand exactly what you're trying to do until you give it a bit more information. The situation I'm going to describe in this post is one such case. By providing the optimizer with...(&lt;a href="http://www2.sqlblog.com/blogs/adam_machanic/archive/2010/01/12/t-sql-tuesday-002-is-it-xml-or-not.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www2.sqlblog.com/aggbug.aspx?PostID=20965" width="1" height="1"&gt;</description><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/puzzle/default.aspx">puzzle</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/xml/default.aspx">xml</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/T-SQL+Tuesday/default.aspx">T-SQL Tuesday</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/_2300_tsql2sday/default.aspx">#tsql2sday</category></item><item><title>T-SQL Challenge: Grouped String Concatenation</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2009/02/27/t-sql-challenge-grouped-string-concatenation.aspx</link><pubDate>Fri, 27 Feb 2009 18:22:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:12307</guid><dc:creator>Adam Machanic</dc:creator><slash:comments>42</slash:comments><comments>http://www2.sqlblog.com/blogs/adam_machanic/comments/12307.aspx</comments><wfw:commentRss>http://www2.sqlblog.com/blogs/adam_machanic/commentrss.aspx?PostID=12307</wfw:commentRss><description>&lt;p&gt;It's been quite a while since the &lt;a href="http://sqlblog.com/blogs/adam_machanic/archive/2008/04/22/sql-server-query-processing-puzzle-like-vs.aspx"&gt;LIKE vs ? Puzzle&lt;/a&gt;,
and I feel like it's time for another one. Response was overwhelming
last time, and I'm back with a much tougher puzzle and a much bigger
prize. So get ready, because I'm going to really make you stretch your
brain and your T-SQL skills for this one.&lt;br&gt;
&lt;/p&gt;&lt;p&gt;But first, a bit of background. String concatenation is &lt;a href="http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/rowset-string-concatenation-which-method-is-best.aspx"&gt;something I've talked about on this blog before&lt;/a&gt;,
and it is an incredibly popular topic; my post on the subject has
gotten more hits than any other single post I've ever done. TechNet
blogger Ward Pond also understands the popularity of the topic, having &lt;a href="http://blogs.technet.com/wardpond/archive/2008/03/13/database-programming-the-string-concatenation-xml-trick.aspx"&gt;discussed&lt;/a&gt; &lt;a href="http://blogs.technet.com/wardpond/archive/2008/03/15/database-programming-the-string-concatenation-xml-trick-revisited-or-adam-is-right-but-we-can-fix-it.aspx"&gt;concatenation&lt;/a&gt; at &lt;a href="http://blogs.technet.com/wardpond/archive/2008/03/18/database-programming-the-string-concatenation-xml-trick-sans-entitization.aspx"&gt;least&lt;/a&gt; &lt;a href="http://blogs.technet.com/wardpond/archive/2008/03/21/database-programming-the-string-concatenation-xml-trick-finalized.aspx"&gt;five&lt;/a&gt; &lt;a href="http://blogs.technet.com/wardpond/archive/2009/02/26/database-programming-the-string-concatenation-xml-trick-revisited.aspx"&gt;times&lt;/a&gt; on his blog. And as illustrated &lt;a href="http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/"&gt;in this excellent article by Anith Sen&lt;/a&gt;, there are a number of methods available to the intrepid SQL Server explorer; the techniques Ward and I show are just the tip of the iceberg. &lt;/p&gt;&lt;p&gt;And
while all of that is great, there is a deep and troublesome hidden
problem: Nowhere in my post, nor Anith's article, nor Ward's series,
will you find a technique that completely solves the concatenation
problem. The FOR XML PATH('') method--by far the most popular SQL
Server 2005 "trick" I see repeated over and over in these articles and
on forums--is a bit limiting. It doesn't help when we need to "group"
our string concatenation, i.e. concatenate strings for a number of key
values and return multiple rows in the result. And FOR XML PATH('')
also leaves us a bit flat if we need to return aggregated data with the
concatenated strings or--even more interesting--concatenate multiple
different columns in the same output. &lt;/p&gt;&lt;p&gt;Sure, there are ways to
solve this problem, but they usually require temp tables, user-defined
functions (CLR or otherwise), tables of numbers, cursors, or other
adjunct objects. And while some of these solutions are certainly
workable they lack the beauty of a single, self-contained solution. In
the interest of solving this problem I recently created a challenge for
myself: Figure out how to do "grouped" concatenation using nothing more
than a single T-SQL statement. No temp tables. No UDFs. No procedural
logic. &lt;/p&gt;&lt;p&gt;But rather than do the work all alone and simply post my
solution, I've decided to invite you to join me in the quest. Are you
up for it?&lt;br&gt;&lt;/p&gt;&lt;p&gt;Here are the rules of the game:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;You are
to create a single T-SQL statement that concatenates values from the
AdventureWorks (note: not AdventureWorks2008) Sales.SalesOrderHeader,
Sales.SalesOrderDetail, Production.Product, and Person.Contact tables. &lt;br&gt;
&lt;/li&gt;&lt;li&gt;The output should have the following columns, in the following order, and no other columns:&lt;br&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;CustomerID: The customer's CustomerID (this is the unique key in the output)&lt;br&gt;&lt;/li&gt;&lt;li&gt;FirstName: The customer's first name&lt;/li&gt;&lt;li&gt;LastName: The customer's last name&lt;br&gt;&lt;/li&gt;&lt;li&gt;OrderCount: Number of orders placed by the customer&lt;/li&gt;&lt;li&gt;TotalDollarAmount: Total dollar amount of all orders placed by the customer (based on the SalesOrderHeader.SubTotal column)&lt;/li&gt;&lt;li&gt;TotalProductQuantity: Total number of items purchased by the customer in all orders (based on SalesOrderDetail.OrderQty)&lt;br&gt;&lt;/li&gt;&lt;li&gt;OrderNumbers:
Comma-delimited list containing the order numbers
(SalesOrderHeader.SalesOrderNumber) for each of the orders placed by
the customer&lt;/li&gt;&lt;ul&gt;&lt;li&gt;The numbers within the list should be alphabetized. The list
should have neither leading nor trailing commas, and each element in
the list should be separated by a single comma with no spaces or other
white space beforeor after the comma &lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;ProductNames: Comma-delimited list containing the unique names of all products ordered by the customer in all orders&lt;/li&gt;&lt;ul&gt;&lt;li&gt;The names within the list should be alphabetized. The list should have neither leading nor trailing commas, and each
element in the list should be separated by a single comma with no
spaces or other white space beforeor after the comma&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li&gt;No tables--permanent, temporary, or variable--are to be
created. No dynamic SQL is to be used. No user-defined functions,
views, or stored procedures are allowed. No variables may be declared.
To put it simply, no permanent or temporary objects of any kind, at any
scope, are to be explicitly created. No procedural statements of any
kind--cursors or control-of-flow--are allowed. This must be a
standalone statement in the AdventureWorks database; nothing more and
nothing less.&lt;br&gt;&lt;/li&gt;&lt;li&gt;Aside from the previous stipulation, any SQL
Server 2005 or 2008 feature is fair game. Documented or not, if it
ships with the product and can be used in a standalone T-SQL statement,
you can use it. If you do use a version-specific feature, please let me
know (especially if it's a SQL Server 2005 feature that's gone in
2008). Bonus points may be given for solutions that work on either
version, but I'll make that decision after reviewing the submissions.&lt;/li&gt;&lt;li&gt;Entries
will be judged first and foremost on correctness, then on a combination
of performance, readability, and ability to apply your technique as a
general pattern. &lt;br&gt;
&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Just to be absolutely clear: If your submission violates the
rules, outputs the wrong data, or does not precisely follow the output
guidelines listed above, it will be ignored. Last time I spent a lot of
energy going back and forth with people helping them get there, and I
just don't have the bandwidth to do that again. So double-check your
submission before you send it to me.&lt;/li&gt;&lt;li&gt;Make your submission readable or you will lose credit even if
performance is amazing. I don't appreciate looking at a mess, and it's
good for your career to learn how to write code that others can
maintain. Hint: Learn to indent your code properly; lack of indentation
is the biggest mistake I see people make with regard to readability.&lt;/li&gt;&lt;li&gt;Take your time. You have two weeks to work on this. I've
already come up with three different solutions that have vastly
different performance characteristics. Perhaps your first shot isn't
the best choice?&lt;br&gt;
    &lt;/li&gt;&lt;/ul&gt;&lt;li&gt;The entry deadline is March 16, 2009, midnight GMT. No exceptions.&lt;/li&gt;&lt;li&gt;Submissions should be e-mailed to me, using a .SQL file attachment. &lt;br&gt;
&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Do not paste your solution into the body of your e-mail&lt;/li&gt;&lt;li&gt;The subject of your e-mail should be "Grouped String Challenge Submission". &lt;br&gt;
    &lt;/li&gt;&lt;li&gt;E-mail your submissions to [my first name] [at] [this site]. &lt;br&gt;
    &lt;/li&gt;&lt;li&gt;Again, be careful and don't violate these guidelines or your submission will be ignored.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;... What's that? You want a prize? Fine, fine ...&lt;/li&gt;&lt;ul&gt;&lt;li&gt;The prize, for the best submission, is a full MSDN subscription, valued at around $10,000. How's that for inspiration?&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;... and that's that! One final note: Please &lt;b&gt;do not post your solution&lt;/b&gt;
in the comments here or on another blog, before the deadline has been
reached! Last time several people did that and it was incredibly
annoying both for me and those contestants trying to think through the
problem. You won't be doing yourself any favors by trying to mess up
the competition.&lt;/p&gt;&lt;p&gt;Once the deadline is reached I will test all of
the submissions, tabulate the results, and post back here in early
April. I promise, I won't let the thing stagnate for months like I did
last time. &lt;/p&gt;&lt;p&gt;Have fun with it, be creative, and feel free to post comments here with any questions you might have. I found this to be a fairly difficult but very interesting exercise and I hope you agree. Enjoy, and I'm looking forward to seeing what you can do!&lt;br&gt;
&lt;/p&gt;&lt;img src="http://www2.sqlblog.com/aggbug.aspx?PostID=12307" width="1" height="1"&gt;</description><enclosure url="http://www2.sqlblog.com/blogs/adam_machanic/attachment/12307.ashx" length="1015924" type="application/zip" /><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/T-SQL/default.aspx">T-SQL</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/puzzle/default.aspx">puzzle</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/contest/default.aspx">contest</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/challenge/default.aspx">challenge</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/grouping/default.aspx">grouping</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/concatenation/default.aspx">concatenation</category></item><item><title>SQL Server Query Processing Puzzle: LIKE vs ?</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2008/04/22/sql-server-query-processing-puzzle-like-vs.aspx</link><pubDate>Tue, 22 Apr 2008 14:18:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:6344</guid><dc:creator>Adam Machanic</dc:creator><slash:comments>33</slash:comments><comments>http://www2.sqlblog.com/blogs/adam_machanic/comments/6344.aspx</comments><wfw:commentRss>http://www2.sqlblog.com/blogs/adam_machanic/commentrss.aspx?PostID=6344</wfw:commentRss><description>&lt;p&gt;How creative are you with manipulating your queries to produce more efficient plans? Try the following puzzle and e-mail your solution to me at [&amp;lt;do_not_mail&amp;gt; @ do_not_mail.com].  Make sure to include an explanation of why it works, as well as your mailing address. The best two solutions/explanations win a free copy of &lt;a href="http://www.amazon.com/dp/159059729X"&gt;Expert SQL Server 2005 Development&lt;/a&gt;, a wonderful feeling of accomplishment, plus eternal fame and glory when I reveal your solutions here on the blog.

&lt;/p&gt;&lt;p&gt;Run the following T-SQL to create two tables in TempDB:
&lt;/p&gt;&lt;pre style="margin-left:40px;"&gt;USE TempDB&lt;br&gt;GO&lt;br&gt;&lt;br&gt;CREATE TABLE b1 (blat1 CHAR(5) NOT NULL)&lt;br&gt;CREATE TABLE b2 (blat2 VARCHAR(200) NOT NULL)&lt;br&gt;GO&lt;br&gt;&lt;br&gt;INSERT b1&lt;br&gt;SELECT LEFT(AddressLine1, 5) AS blat1&lt;br&gt;FROM AdventureWorks.Person.Address&lt;br&gt;&lt;br&gt;INSERT b2&lt;br&gt;SELECT AddressLine1 AS blat2&lt;br&gt;FROM AdventureWorks.Person.Address&lt;br&gt;GO&lt;/pre&gt;
Now consider the following query:
&lt;pre style="margin-left:40px;"&gt;SELECT *&lt;br&gt;FROM b1&lt;br&gt;JOIN b2 ON&lt;br&gt;    b2.blat2 LIKE b1.blat1 + '%'&lt;/pre&gt;&lt;p&gt;
This query takes around three minutes to run on my notebook, and does over 1.8 million logical reads.  Can you figure out a way to re-write it so that it performs better?  No modification of the base tables or addition of any other objects is allowed (sorry, no indexed views!) -- the challenge is to tune this by doing nothing more than re-writing the query.

&lt;/p&gt;&lt;p&gt;Good luck!  I'll leave the contest open for submissions until May 1.&lt;/p&gt;&lt;img src="http://www2.sqlblog.com/aggbug.aspx?PostID=6344" width="1" height="1"&gt;</description><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/Performance/default.aspx">Performance</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/Query+Tuning/default.aspx">Query Tuning</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/puzzle/default.aspx">puzzle</category></item></channel></rss>