<?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>OS与Oracle &#187; connect_by_root</title>
	<atom:link href="http://www.os2ora.com/tag/connect_by_root/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.os2ora.com</link>
	<description>专注于现实世界Oracle数据库的高性能，高可扩展性与新一代数据库Exadata架构</description>
	<lastBuildDate>Mon, 19 Sep 2011 09:10:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>如何实现组织结构中的汇总统计</title>
		<link>http://www.os2ora.com/how-to-hierarchical-summary/</link>
		<comments>http://www.os2ora.com/how-to-hierarchical-summary/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 11:20:32 +0000</pubDate>
		<dc:creator>Kaya</dc:creator>
				<category><![CDATA[Oracle SQL 扩展]]></category>
		<category><![CDATA[connect by]]></category>
		<category><![CDATA[connect_by_root]]></category>
		<category><![CDATA[group by]]></category>
		<category><![CDATA[Hierarchical Queries]]></category>
		<category><![CDATA[salary]]></category>
		<category><![CDATA[summary]]></category>

		<guid isPermaLink="false">http://www.os2ora.com/how-to-hierarchical-summary/</guid>
		<description><![CDATA[汇总统计是数据处理中常见的一个操作。对于一般的数据模型来说，一般是有一个事实表，若干个维度表，通过事实表与维度表的连接，实现不同层次的查询汇总。 
问题是对于组织结构而言，一般所有的数据都存贮于一个表中，而且，组织结构的层次也是动态的。那么，在这种情况下，如何实现员工工资的汇总呢？一个比较有趣的问题是: 如何统计员工及其所有被管理员工的总工资，举个例子，CEO的总工资就是整个公司总有员工的总工资之和，包括他自己......]]></description>
			<content:encoded><![CDATA[<p>Kaya 发表于 <a href="http://www.os2ora.com">os2ora.com</a></p>
<p>汇总统计是数据处理中常见的一个操作。对于一般的数据模型来说，一般是有一个事实表，若干个维度表，通过事实表与维度表的连接，实现不同层次的查询汇总。<br />
问题是对于组织结构而言，一般所有的数据都存贮于一个表中，而且，组织结构的层次也是动态的。那么，在这种情况下，如何实现员工工资的汇总呢？一个比较有趣的问题是: 如何统计员工及其所有被管理员工的总工资，举个例子，CEO的总工资就是整个公司总有员工的总工资之和，包括他自己。</p>
<p>Oracle 引入了一个扩展的运算符，专门用来处理此种情形，它就是connect_by_root。<br />
当以connect_by_root修饰一个列名时，Oracle将返回根节点对应的此列的值。例如，当start with 为 last_name = &#8216;King&#8217;时，这时返回的所有行的connect_by_root last_name的值都将为&#8217;King&#8217;。这时，对所有行的累计就是对&#8217;King&#8217;的数据的累计了。当不指定start with 子句时，Oracle将对每个节点依次进行遍历，于是，我们可以对返回的结果对last_name进行一次group by，那么我们就得到了所有last_name对应的汇总工资了。</p>
<p>下面是Oracle 文档中的例子。<br />
The following example returns the last name of each employee in department 110, each manager above that employee in the hierarchy, the number of levels between manager and employee, and the path between the two:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> last_name <span style="color: #ff0000;">&quot;Employee&quot;</span><span style="color: #66cc66;">,</span> CONNECT_BY_ROOT last_name <span style="color: #ff0000;">&quot;Manager&quot;</span><span style="color: #66cc66;">,</span>
   LEVEL<span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span> <span style="color: #ff0000;">&quot;Pathlen&quot;</span><span style="color: #66cc66;">,</span> SYS_CONNECT_BY_PATH<span style="color: #66cc66;">&#40;</span>last_name<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'/'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;Path&quot;</span>
   <span style="color: #993333; font-weight: bold;">FROM</span> employees
   <span style="color: #993333; font-weight: bold;">WHERE</span> LEVEL &amp;gt; <span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AND</span> department_id <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">110</span>
   CONNECT <span style="color: #993333; font-weight: bold;">BY</span> PRIOR employee_id <span style="color: #66cc66;">=</span> manager_id
   <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">&quot;Employee&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Manager&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Pathlen&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Path&quot;</span>;
&nbsp;
Employee        Manager            Pathlen Path
<span style="color: #808080; font-style: italic;">--------------- --------------- ---------- ------------------------------</span>
Gietz           Higgins                  <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">/</span>Higgins<span style="color: #66cc66;">/</span>Gietz
Gietz           King                     <span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">/</span>King<span style="color: #66cc66;">/</span>Kochhar<span style="color: #66cc66;">/</span>Higgins<span style="color: #66cc66;">/</span>Gietz
Gietz           Kochhar                  <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">/</span>Kochhar<span style="color: #66cc66;">/</span>Higgins<span style="color: #66cc66;">/</span>Gietz
Higgins         King                     <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">/</span>King<span style="color: #66cc66;">/</span>Kochhar<span style="color: #66cc66;">/</span>Higgins
Higgins         Kochhar                  <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">/</span>Kochhar<span style="color: #66cc66;">/</span>Higgins</pre></div></div>

<p>The following example uses a GROUP BY clause to return the total salary of each employee in department 110 and all employees below that employee in the hierarchy:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> name<span style="color: #66cc66;">,</span> SUM<span style="color: #66cc66;">&#40;</span>salary<span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;Total_Salary&quot;</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#40;</span>
   <span style="color: #993333; font-weight: bold;">SELECT</span> CONNECT_BY_ROOT last_name <span style="color: #993333; font-weight: bold;">AS</span> name<span style="color: #66cc66;">,</span> Salary
      <span style="color: #993333; font-weight: bold;">FROM</span> employees
      <span style="color: #993333; font-weight: bold;">WHERE</span> department_id <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">110</span>
      CONNECT <span style="color: #993333; font-weight: bold;">BY</span> PRIOR employee_id <span style="color: #66cc66;">=</span> manager_id<span style="color: #66cc66;">&#41;</span>
      <span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> name
   <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> name<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">&quot;Total_Salary&quot;</span>;
&nbsp;
NAME                      Total_Salary
<span style="color: #808080; font-style: italic;">------------------------- ------------</span>
Gietz                             <span style="color: #cc66cc;">8300</span>
Higgins                          <span style="color: #cc66cc;">20300</span>
King                             <span style="color: #cc66cc;">20300</span>
Kochhar                          <span style="color: #cc66cc;">20300</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.os2ora.com/how-to-hierarchical-summary/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Oracle的层次结构化查询 &#8212; 基础篇</title>
		<link>http://www.os2ora.com/hierarchical-queries-basic/</link>
		<comments>http://www.os2ora.com/hierarchical-queries-basic/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 09:50:41 +0000</pubDate>
		<dc:creator>Kaya</dc:creator>
				<category><![CDATA[Oracle SQL 扩展]]></category>
		<category><![CDATA[connect by]]></category>
		<category><![CDATA[connect_by_root]]></category>
		<category><![CDATA[Hierarchical Queries]]></category>
		<category><![CDATA[prior]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[start with]]></category>
		<category><![CDATA[tree]]></category>

		<guid isPermaLink="false">http://www.os2ora.com/hierarchical-queries-basic/</guid>
		<description><![CDATA[虽然Oracle不是一个层次型的数据库，不过它却对层次型应有不错的支持。
层次型应用最常见的是一个公司内部的组织结构。
在计算机科学中，或者更具体地说，在数据结构中，层次型结构是由“树”来描述的。节点之间的关系代表着上下两个层次之间节点的关系，即父子关系。这一般是一对多的关系。
一般地，我们会把这一系列的父子关系存贮到数据库里的一个表里面。
而Oracle的任务，就是要重现这棵树，并实现有关层次关系的运算......]]></description>
			<content:encoded><![CDATA[<p>Kaya 发表于 <a href="http://www.os2ora.com">os2ora.com</a></p>
<p>虽然Oracle不是一个层次型的数据库，不过它却对层次型应有不错的支持。</p>
<p>层次型应用最常见的是一个公司内部的组织结构。</p>
<p>在计算机科学中，或者更具体地说，在数据结构中，层次型结构是由“树”来描述的。节点之间的关系代表着上下两个层次之间节点的关系，即父子关系。这一般是一对多的关系。</p>
<p>一般地，我们会把这一系列的父子关系存贮到数据库里的一个表里面。</p>
<p>而Oracle的任务，就是要重现这棵树，并实现有关层次关系的运算。例如，打印出层次结构图，统计层次结构中每个节点对应的直接子节点数，对应的直接子节点和间接子节点数，统计每个节点的所处的层次。</p>
<p>以公司内部组织结构为例，则要求实现对公司组织结构的重现，统计每位经理所直接管理员工的数目，直接和间接管理员工的数目，每位经理所处的级别，还有，每位经理所管理的所有员工的总有工资的总和，等等。</p>
<p>为了实现这些功能，Oracle引入了几个关键词，connect by, prior 和 start with。connect by实现了表中两个直接层次间数据行的连接，而prior则是用来标记哪个是父节点。start with则代表从哪些节点开始遍历。如下图所示:</p>
<p><a href="http://www.os2ora.com/wp-content/uploads/2009/03/image.png"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="image" src="http://www.os2ora.com/wp-content/uploads/2009/03/image-thumb.png" border="0" alt="image" width="479" height="231" /></a></p>
<p>下面是Oracle如何处理connect by 和prior的官方描述<br />
Oracle processes hierarchical queries as follows:<br />
    * A join, if present, is evaluated first, whether the join is specified in the FROM clause or with WHERE clause predicates.<br />
    * The CONNECT BY condition is evaluated.<br />
    * Any remaining WHERE clause predicates are evaluated.</p>
<p>更详细地:<br />
   1. Oracle selects the root row(s) of the hierarchy—those rows that satisfy the START WITH condition.<br />
   2. Oracle selects the child rows of each root row (from all the rows in the table). Each child row must satisfy the condition of the CONNECT BY condition with respect to one of the root rows.<br />
   3. Oracle selects successive generations of child rows. Oracle first selects the children of the rows returned in step 2, and then the children of those children, and so on. Oracle always selects children by evaluating the CONNECT BY condition with respect to a current parent row.<br />
   4. If the query contains a WHERE clause without a join, then Oracle eliminates all rows from the hierarchy that do not satisfy the condition of the WHERE clause. Oracle evaluates this condition for each row individually, rather than removing all the children of a row that does not satisfy the condition.<br />
   5. Oracle returns the rows in the order shown in Figure 9-1. In the diagram, children appear below their parents.</p>
<p>Figure 9-1 Hierarchical Queries</p>
<p><a href="http://www.os2ora.com/wp-content/uploads/2009/03/image1.png"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="image" src="http://www.os2ora.com/wp-content/uploads/2009/03/image-thumb1.png" border="0" alt="image" width="262" height="204" /></a></p>
<p>关于第5点，这就是大家熟悉的树的中序遍历算法。而前面的4点，应该说是一个层次遍历。我想我们更应该记住的是第5点，谁知道Oracle内部具体实现时是不是按照前4点的描述呢。</p>
<p>以上面这个图为例子。我们可以利用Oracle的查询语句打印出类似目录树的输出。做为对基础知识的一个实践。</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> hierarchy <span style="color: #66cc66;">&#40;</span>id number<span style="color: #66cc66;">,</span> parent_id number<span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">7</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">9</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">8</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">7</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">9</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">9</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">6</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> hierarchy<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span>;
col tree format a10
col path format a15
<span style="color: #993333; font-weight: bold;">SELECT</span> level<span style="color: #66cc66;">,</span>rpad<span style="color: #66cc66;">&#40;</span>’<span style="color: #66cc66;">-</span><span style="color: #ff0000;">',level,’-'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">||</span> id tree<span style="color: #66cc66;">,</span> sys_connect_by_path<span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">,</span>’<span style="color: #66cc66;">/</span><span style="color: #ff0000;">') Path, connect_by_root id
from hierarchy
start with parent_id is null
connect by parent_id = prior id;</span></pre></div></div>

<p>输出如下所示:</p>
<p><a href="http://www.os2ora.com/wp-content/uploads/2009/03/image2.png"><img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="image" src="http://www.os2ora.com/wp-content/uploads/2009/03/image-thumb2.png" border="0" alt="image" width="804" height="343" /></a></p>
<p>connect by 和connect_by_root 还有许多有趣的扩展应用。后继文章再详细探讨一下。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.os2ora.com/hierarchical-queries-basic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

