<?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>Thiago Zavaschi R2 &#187; Common Table Expression</title>
	<atom:link href="http://zavaschi.com/index.php/tag/common-table-expression/feed/" rel="self" type="application/rss+xml" />
	<link>http://zavaschi.com</link>
	<description>www.zavaschi.com</description>
	<lastBuildDate>Mon, 02 Jan 2012 16:51:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Entendendo as Common Table Expressions &#8211; CTE &#8211; Parte 3 (O Retorno)</title>
		<link>http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-3-o-retorno/</link>
		<comments>http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-3-o-retorno/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 12:24:12 +0000</pubDate>
		<dc:creator>Thiago Zavaschi</dc:creator>
				<category><![CDATA[Common Table Expression]]></category>
		<category><![CDATA[CTE]]></category>

		<guid isPermaLink="false">8DE5A8EFC1819ECA!399</guid>
		<description><![CDATA[Sabe quando você termina uma coisa, mas fica na cabeça de que esqueceu alguma coisa?
Poisé… alguns dos meus posts anteriores trataram de Common Table Expressions e eu não mencionei outra característica muito interessante.
Lembram que o result set da CTE só existe no escopo da query seguinte? Mas será que não é possivél eu ir juntando [...]]]></description>
			<content:encoded><![CDATA[<p>Sabe quando você termina uma coisa, mas fica na cabeça de que esqueceu alguma coisa?
<p>Poisé… alguns dos meus posts anteriores trataram de Common Table Expressions e eu não mencionei outra característica muito interessante.
<p>Lembram que o <em>result set</em> da CTE só existe no escopo da query seguinte? Mas será que não é possivél eu ir juntando várias CTE’s e no final fazer uma query que manipule o conjunto de todas?
<p>É sim! Vejam o seguinte exemplo: </p>
<div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px">
<pre style="background-color:WhiteSmoke;overflow:auto"><span style="color:#000000">;</span><span style="color:#0000FF">WITH</span><span style="color:#000000"> cteA(a)
</span><span style="color:#0000FF">AS</span><span style="color:#000000">
(
    </span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">1</span><span style="color:#000000">
    </span><span style="color:#0000FF">UNION</span><span style="color:#000000"> </span><span style="color:#808080">ALL</span><span style="color:#000000">
    </span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> a </span><span style="color:#808080">+</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">1</span><span style="color:#000000"> </span><span style="color:#0000FF">FROM</span><span style="color:#000000"> cteA </span><span style="color:#0000FF">WHERE</span><span style="color:#000000"> a </span><span style="color:#808080">&lt;</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">10</span><span style="color:#000000">
), cteB(b)
</span><span style="color:#0000FF">AS</span><span style="color:#000000">
(
    </span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">1</span><span style="color:#000000">
    </span><span style="color:#0000FF">UNION</span><span style="color:#000000"> </span><span style="color:#808080">ALL</span><span style="color:#000000">
    </span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> b </span><span style="color:#808080">+</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">1</span><span style="color:#000000"> </span><span style="color:#0000FF">FROM</span><span style="color:#000000"> cteB </span><span style="color:#0000FF">WHERE</span><span style="color:#000000"> b </span><span style="color:#808080">&lt;</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">10</span><span style="color:#000000">
), cteC(c)
</span><span style="color:#0000FF">AS</span><span style="color:#000000">
(
    </span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">5</span><span style="color:#000000">
)
</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> ((</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#FF00FF">SUM</span><span style="color:#000000">(b) </span><span style="color:#0000FF">from</span><span style="color:#000000"> cteB) </span><span style="color:#808080">+</span><span style="color:#000000"> (</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#FF00FF">SUM</span><span style="color:#000000">(a) </span><span style="color:#0000FF">from</span><span style="color:#000000"> cteA)) </span><span style="color:#808080">/</span><span style="color:#000000">
((</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#FF00FF">COUNT</span><span style="color:#000000">(b) </span><span style="color:#0000FF">from</span><span style="color:#000000"> cteB) </span><span style="color:#808080">+</span><span style="color:#000000"> (</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#FF00FF">COUNT</span><span style="color:#000000">(a) </span><span style="color:#0000FF">from</span><span style="color:#000000"> cteA)) </span><span style="color:#808080">*</span><span style="color:#000000">
(</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> c </span><span style="color:#0000FF">FROM</span><span style="color:#000000"> cteC)</span></pre>
</div>
<p>São 3 CTEs sendo executadas. O retorno das duas primeiras já nos é conhecido: é a contagem de 1 a 10 (visto no post anterior), e o retorno da última é 5, bastante trivial.</p>
<p>Esse post não serve apenas para demonstrar essa capacidade, mas também para alertar para os perigos que podem vir atrelados. </p>
<p>E o meu recado é: <strong><em>CUIDADO com a comodidade!</em></strong> Senão a legibilidade ganha com as CTEs de nada servirá. A explicação é facilmente observada através do plano de execução da query acima.</p>
<p><font size="2" face="Courier New">StmtText<br />----------------------------------------------------------------------------------------------------------------------<br />  |--Compute Scalar(DEFINE:([Expr1026]=(([Expr1004]+[Expr1010])/([Expr1016]+[Expr1022]))*(5)))<br />       |--Nested Loops(Inner Join)<br />            |--Nested Loops(Inner Join)<br />            |    |--Nested Loops(Inner Join)<br />            |    |    |--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [Expr1045]=(0) THEN NULL ELSE [Expr1046] END))<br />            |    |    |    |--Stream Aggregate(DEFINE:([Expr1045]=COUNT_BIG([Recr1003]), [Expr1046]=SUM([Recr1003])))<br />            |    |    |         |--Index Spool(WITH STACK)<br />            |    |    |              |--Concatenation<br />            |    |    |                   |--Compute Scalar(DEFINE:([Expr1041]=(0)))<br />            |    |    |                   |    |--Constant Scan(VALUES:(((1))))<br />            |    |    |                   |--Assert(WHERE:(CASE WHEN [Expr1043]&gt;(100) THEN (0) ELSE NULL END))<br />            |    |    |                        |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1043], [Recr1001]))<br />            |    |    |                             |--Compute Scalar(DEFINE:([Expr1043]=[Expr1042]+(1)))<br />            |    |    |                             |    |--Table Spool(WITH STACK)<br />            |    |    |                             |--Compute Scalar(DEFINE:([Expr1002]=[Recr1001]+(1)))<br />            |    |    |                                  |--Filter(WHERE:(STARTUP EXPR([Recr1001]&lt;(10))))<br />            |    |    |                                       |--Constant Scan<br />            |    |    |--Compute Scalar(DEFINE:([Expr1022]=CONVERT_IMPLICIT(int,[Expr1051],0)))<br />            |    |         |--Stream Aggregate(DEFINE:([Expr1051]=COUNT([Recr1021])))<br />            |    |              |--Index Spool(WITH STACK)<br />            |    |                   |--Concatenation<br />            |    |                        |--Compute Scalar(DEFINE:([Expr1047]=(0)))<br />            |    |                        |    |--Constant Scan(VALUES:(((1))))<br />            |    |                        |--Assert(WHERE:(CASE WHEN [Expr1049]&gt;(100) THEN (0) ELSE NULL END))<br />            |    |                             |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1049], [Recr1019]))<br />            |    |                                  |--Compute Scalar(DEFINE:([Expr1049]=[Expr1048]+(1)))<br />            |    |                                  |    |--Table Spool(WITH STACK)<br />            |    |                                  |--Compute Scalar(DEFINE:([Expr1020]=[Recr1019]+(1)))<br />            |    |                                       |--Filter(WHERE:(STARTUP EXPR([Recr1019]&lt;(10))))<br />            |    |                                            |--Constant Scan<br />            |    |--Compute Scalar(DEFINE:([Expr1016]=CONVERT_IMPLICIT(int,[Expr1056],0)))<br />            |         |--Stream Aggregate(DEFINE:([Expr1056]=COUNT([Recr1015])))<br />            |              |--Index Spool(WITH STACK)<br />            |                   |--Concatenation<br />            |                        |--Compute Scalar(DEFINE:([Expr1052]=(0)))<br />            |                        |    |--Constant Scan(VALUES:(((1))))<br />            |                        |--Assert(WHERE:(CASE WHEN [Expr1054]&gt;(100) THEN (0) ELSE NULL END))<br />            |                             |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1054], [Recr1013]))<br />            |                                  |--Compute Scalar(DEFINE:([Expr1054]=[Expr1053]+(1)))<br />            |                                  |    |--Table Spool(WITH STACK)<br />            |                                  |--Compute Scalar(DEFINE:([Expr1014]=[Recr1013]+(1)))<br />            |                                       |--Filter(WHERE:(STARTUP EXPR([Recr1013]&lt;(10))))<br />            |                                            |--Constant Scan<br />            |--Compute Scalar(DEFINE:([Expr1010]=CASE WHEN [Expr1061]=(0) THEN NULL ELSE [Expr1062] END))<br />                 |--Stream Aggregate(DEFINE:([Expr1061]=COUNT_BIG([Recr1009]), [Expr1062]=SUM([Recr1009])))<br />                      |--Index Spool(WITH STACK)<br />                           |--Concatenation<br />                                |--Compute Scalar(DEFINE:([Expr1057]=(0)))<br />                                |    |--Constant Scan(VALUES:(((1))))<br />                                |--Assert(WHERE:(CASE WHEN [Expr1059]&gt;(100) THEN (0) ELSE NULL END))<br />                                     |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1059], [Recr1007]))<br />                                          |--Compute Scalar(DEFINE:([Expr1059]=[Expr1058]+(1)))<br />                                          |    |--Table Spool(WITH STACK)<br />                                          |--Compute Scalar(DEFINE:([Expr1008]=[Recr1007]+(1)))<br />                                               |--Filter(WHERE:(STARTUP EXPR([Recr1007]&lt;(10))))<br />                                                    |--Constant Scan </font></p>
<p>Poisé, é executado tudo separado. Se houverem processamento desnecessários nas CTEs, poderemos encontrar sérios gargalos nestas querys!</p>
<p>Então pessoal, era mais isso que eu queria mostrar deste fantástico recurso! Usem CTE’s, e para os que usarem, usem sabendo como funcionam! :)</p>
<p>E para quem não acompanhou, segue os links dos posts anteriores:</p>
<h6>Entendendo as Common Table Expressions – CTE – Parte 1</h6>
<p><a title="http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!390.entry" href="http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!390.entry">http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!390.entry</a></p>
<h6>Entendendo as Common Table Expressions – CTE – Parte 2 (Final)</h6>
<p><a title="http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!391.entry" href="http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!391.entry">http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!391.entry</a></p>
<p>Abraços,<br />Thiago Zavaschi</p>
]]></content:encoded>
			<wfw:commentRss>http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-3-o-retorno/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

