<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Seree Woradechjamroen &#187; sql tricks</title>
	<atom:link href="http://www.iamseree.com/tag/sql-tricks/feed" rel="self" type="application/rss+xml" />
	<link>http://www.iamseree.com</link>
	<description>Keep learning everyday, willing to win and take action</description>
	<lastBuildDate>Tue, 15 May 2012 16:06:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>SQL Tricks #1</title>
		<link>http://www.iamseree.com/application-development/sql-tricks-1</link>
		<comments>http://www.iamseree.com/application-development/sql-tricks-1#comments</comments>
		<pubDate>Sun, 16 Sep 2007 06:55:28 +0000</pubDate>
		<dc:creator>Seree</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[sql puzzle]]></category>
		<category><![CDATA[sql tips]]></category>
		<category><![CDATA[sql tricks]]></category>

		<guid isPermaLink="false">http://www.iamseree.com/?p=21</guid>
		<description><![CDATA[<p>Hello all,</p> <p>After my last few Transact-SQL training courses, one of my trainee had ask me on this scenario and I thinks it should be useful for most of people who are not concern much about SQL query performance which produce better processing time when compared to generic coding to query the result. You may [...]]]></description>
			<content:encoded><![CDATA[<p>Hello all,</p>
<p>After my last few Transact-SQL training courses, one of my trainee had ask me on this scenario and I thinks it should be useful for most of people who are not concern much about SQL query performance which produce better processing time when compared to generic coding to query the result. You may not clear about what I&#8217;m writing now. Just see the following scenario.</p>
<p>Assume I have a table named [Book] which has the following structure.</p>
<blockquote><p>- BookId as int &#8211; identity(1,1) &#8211; Primary key<br />
- Title as varchar(100)<br />
- Price as int</p></blockquote>
<p>Then I assume that manager want a report just like this.</p>
<blockquote>
<table border="1" cellspacing="0" cellpadding="2" width="373">
<tbody>
<tr>
<td width="164" valign="top"><strong>Title</strong></td>
<td width="67" valign="top"><strong>Price</strong></td>
<td width="139" valign="top"><strong>Price Range</strong></td>
</tr>
<tr>
<td width="163" valign="top">Advanced SQL</td>
<td width="67" valign="top">25</td>
<td width="139" valign="top">Expensive</td>
</tr>
<tr>
<td width="162" valign="top">Intermediate C#</td>
<td width="67" valign="top">12</td>
<td width="139" valign="top">Cheap</td>
</tr>
</tbody>
</table>
</blockquote>
<p>You should see the column &#8220;Price Range&#8221; which do not reside in the table structure. Continue, I assume that if the price is expensive than 20 then I count as &#8220;Expensive&#8221; price range. If the price is less than 15 then I count as &#8220;Cheap&#8221;.</p>
<p><strong>How should you do this report?</strong></p>
<p>Most of my trainee do the following method.</p>
<p>1. Create an application then query for the columns [Title, Price].</p>
<p>2. They create a new column in report. In case of ASP.NET, they add a new template column into GridView.</p>
<p>3. In querying event for every record. (Such as Item data bound) They coding to check the condition whether the current record is expensive or cheap then output it.</p>
<p><!--adsense--></p>
<p><strong>Are there a better solution?</strong></p>
<p>Certainly, If you focus on SQL query optimization. You should got a point to improve the performance of this process.</p>
<p>Let&#8217;s see the key.<span id="more-21"></span></p>
<p><em>Do you know about &#8220;CASE WHEN&#8221; statement in SQL?</em></p>
<p>Try to figure this query. Especially at the <span style="color: #22ffff;">high-light</span>.</p>
<blockquote><p>SELECT Title, Price,<br />
<span style="color: #22ffff;">CASE<br />
WHEN price &gt; 20 THEN &#8216;Expensive&#8217;<br />
WHEN price BETWEEN 15 AND 20 THEN &#8216;Medium&#8217;<br />
ELSE &#8216;Cheap&#8217;<br />
END<br />
</span>As &#8216;Price Range&#8217;<br />
FROM [Book]</p></blockquote>
<p>With this method, you never do some additional tasks like &#8220;adding template column&#8221; and &#8220;coding for price range&#8221;. You just binding this query to the GridView. I call this method &#8220;Column morphing&#8221; as with this method, you can create new column without structured on the table&#8217;s schema and can set the value in the column with any logical that SQL statement support.</p>
<p><strong>So, does it better than the first method?</strong></p>
<p>Definitely sure. Both on performance and less task effort. You can do more about &#8220;Column morphing&#8221; with the integration of <em>sub-query</em>. Just like the following case.</p>
<blockquote><p>SELECT Title, Price,<br />
CASE<br />
WHEN Price &gt; (SELECT AVG(Price) FROM [Book]) THEN &#8216;More than average&#8217;<br />
WHEN Price = (SELECT AVG(price) FROM [Book]) THEN &#8216;Equal to average&#8217;<br />
ELSE &#8216;Less then average&#8217;<br />
END<br />
As &#8216;Price Range&#8217;<br />
FROM [Book]</p></blockquote>
<p>Even more flexible when integrate with <em>correlated sub-query</em>. See the following more advanced case.</p>
<blockquote><p>SELECT Title, Price,<br />
CASE<br />
WHEN Price &gt; <span style="color: #22ffff;">b.avgPrice</span> THEN &#8216;More than average&#8217;<br />
WHEN Price = <span style="color: #22ffff;">b.avgPrice</span> FROM [Book]) THEN &#8216;Equal to average&#8217;<br />
ELSE &#8216;Less then average&#8217;<br />
END<br />
FROM [Book], <span style="color: #22ffff;">(SELECT AVG(price) AS &#8216;avgPrice&#8217; FROM [Book]) b</span></p></blockquote>
<p>The last query will produce the same result as the previous one. (see if the current record is expensive than the average price or not) Except what each method actually process is very different.</p>
<p>In the 1st method, the average price calculation will be processed in every record. Think that If you have 100 records then it will calculate 100 times. Pain or not?</p>
<p>But the 2nd method will do the different. As you seen in the correlated sub-query. (which I&#8217;ve high-lighted as brown) You see that I put the average price calculation after FROM clause. This will force SQL parser to calculate the average price once and kept in alias table &#8216;<strong><em><span style="color: #22ffff;">b</span></em></strong>&#8216;. This will generate much better in case of you&#8217;ve so much number of record to process.</p>
<p><strong>Conclusion</strong></p>
<p>It&#8217;s good to do what you can in SQL query as they&#8217;ve been optimized by database engine-self. If possible, provide as stored procedure is the best way to do as it will provide the fastest performance since the execution plan of query will be cached in memory. Got fast!</p>
<p><!--adsense--></p>
<div align="left" style="float: ; padding: 5px 5px 0px 0px;"><a name="fb_share" type="button" share_url="http://www.iamseree.com/application-development/sql-tricks-1"></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.iamseree.com/application-development/sql-tricks-1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

