<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6817090233381397254</id><updated>2011-04-21T21:38:38.153+02:00</updated><category term='Bienvenida'/><title type='text'>Business Intelligence World</title><subtitle type='html'>Este blog contiene post acerca del mundo de BI, tanto desarrollo como  administración, sobre diferentes plataformas</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://olapdevelopment.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6817090233381397254/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://olapdevelopment.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Oscar</name><uri>http://www.blogger.com/profile/14247779861110707894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6817090233381397254.post-4996508575711418275</id><published>2008-11-10T16:02:00.001+01:00</published><updated>2008-11-10T16:02:35.045+01:00</updated><title type='text'>Gestión de jerarquías en SQL Server(II) : CTE’s</title><content type='html'>&lt;p align="justify"&gt;Otra forma de gestionar las jerarquías que proporciona SQL Server son los Common Table Expression (en adelante CTE). Los CTE son expresiones similares a las vistas o a las consultas derivadas (subconsultas) que permiten crear una consulta temporal que puede ser referenciada desde una instrucción DML. Básicamente este tipo de expresiones es muy similar a los miembros calculados que se definen en MDX, claro está, teniendo en cuenta que se trata de un lenguaje relacional. Esto anterior lo digo porque se usa de la siguiente forma&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;WITH&lt;/span&gt; nombre_expresion &lt;span style="color: #808080"&gt;[&lt;/span&gt; &lt;span style="color: #808080"&gt;(&lt;/span&gt; nombre_columna &lt;span style="color: #808080"&gt;[&lt;/span&gt; ,...&lt;span style="color: #202020"&gt;n&lt;/span&gt; &lt;span style="color: #808080"&gt;]&lt;/span&gt; &lt;span style="color: #808080"&gt;)&lt;/span&gt; &lt;span style="color: #808080"&gt;]&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; &lt;span style="color: #808080"&gt;(&lt;/span&gt; definicion_contenido_cte &lt;span style="color: #808080"&gt;)&lt;/span&gt;     &lt;br /&gt;Instruccion DML&lt;/div&gt;  &lt;p&gt;Como entiendo que se ve mucho más claro con un ejemplo, os presento el siguiente:&lt;/p&gt;  &lt;p&gt;Lo que se quiere hacer es obtener el máximo en la lista de precios consolidada de productos en stock. Esto se haría en SQL Server 2005 como sigue &lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; p.IDSubcategoria, s.&lt;span style="color: #202020"&gt;Nombre&lt;/span&gt;, &lt;span style="color: #ff00ff"&gt;SUM&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;Precio&lt;span style="color: #808080"&gt;)&lt;/span&gt; &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; SumaPrecios     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; #Temp1     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; &lt;span style="color: #202020"&gt;Producto&lt;/span&gt; p     &lt;br /&gt;&lt;span style="color: #808080"&gt;JOIN&lt;/span&gt;&amp;#160;&lt;span style="color: #202020"&gt;SubcategoriaProducto&lt;/span&gt; s &lt;span style="color: #0000ff"&gt;ON&lt;/span&gt; s.IDSubcategoria &lt;span style="color: #808080"&gt;=&lt;/span&gt;     &lt;br /&gt;p.&lt;span style="color: #202020"&gt;IDSubcategoria&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; p.IDSubcategoria &lt;span style="color: #0000ff"&gt;IS&lt;/span&gt; &lt;span style="color: #808080"&gt;NOT&lt;/span&gt; &lt;span style="color: #808080"&gt;NULL&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;GROUP&lt;/span&gt; &lt;span style="color: #0000ff"&gt;BY&lt;/span&gt; p.IDSubcategoria, s.&lt;span style="color: #202020"&gt;Nombre&lt;/span&gt;     &lt;br /&gt;    &lt;br /&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; IDSubcategoria, Nombre, &lt;span style="color: #ff00ff"&gt;MAX&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;SumaPrecios&lt;span style="color: #808080"&gt;)&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; #Temp1     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;GROUP&lt;/span&gt; &lt;span style="color: #0000ff"&gt;BY&lt;/span&gt; IDSubcategoria, Nombre     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;HAVING&lt;/span&gt; &lt;span style="color: #ff00ff"&gt;MAX&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;SumaPrecios&lt;span style="color: #808080"&gt;)&lt;/span&gt; &lt;span style="color: #808080"&gt;=&lt;/span&gt; &lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; &lt;span style="color: #ff00ff"&gt;MAX&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;SumaPrecios&lt;span style="color: #808080"&gt;)&lt;/span&gt; &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; #Temp1&lt;span style="color: #808080"&gt;)&lt;/span&gt;     &lt;br /&gt;    &lt;br /&gt;&lt;span style="color: #0000ff"&gt;DROP&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TABLE&lt;/span&gt; #Temp1&lt;/div&gt;  &lt;p&gt;Como vemos lo que hace es sumar los precios de cada lista agrupados por lista y después obtener el máximo. Con los nuevos CTE esta query quedaría de la siguiente forma:&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;WITH&lt;/span&gt; ListaProductos &lt;span style="color: #808080"&gt;(&lt;/span&gt;IDSubcategoria, Nombre, SumaPrecios&lt;span style="color: #808080"&gt;)&lt;/span&gt; &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; p.IDSubcategoria, s.&lt;span style="color: #202020"&gt;Nombre&lt;/span&gt;, &lt;span style="color: #ff00ff"&gt;SUM&lt;/span&gt;&lt;span style="color: #808080"&gt;(Precio&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt; &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; SumaPrecios     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; &lt;span style="color: #202020"&gt;Producto&lt;/span&gt; p     &lt;br /&gt;&lt;span style="color: #808080"&gt;JOIN&lt;/span&gt; SubcategoriaProducto s &lt;span style="color: #0000ff"&gt;ON&lt;/span&gt; s.IDSubcategoria &lt;span style="color: #808080"&gt;=&lt;/span&gt;     &lt;br /&gt;p.IDSubcategoria     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; p.IDSubcategoria&lt;span style="color: #0000ff"&gt;IS&lt;/span&gt; &lt;span style="color: #808080"&gt;NOT&lt;/span&gt; &lt;span style="color: #808080"&gt;NULL&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;GROUP&lt;/span&gt; &lt;span style="color: #0000ff"&gt;BY&lt;/span&gt; p.IDSubcategoria, s.&lt;span style="color: #202020"&gt;Nombre&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; IDSubcategoria, Nombre, &lt;span style="color: #ff00ff"&gt;MAX&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;SumaPrecios&lt;span style="color: #808080"&gt;)&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; ListaProductos     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;GROUP&lt;/span&gt; &lt;span style="color: #0000ff"&gt;BY&lt;/span&gt; IDSubcategoria, Nombre     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;HAVING&lt;/span&gt; &lt;span style="color: #ff00ff"&gt;MAX&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;SumaPrecios&lt;span style="color: #808080"&gt;)&lt;/span&gt; &lt;span style="color: #808080"&gt;=&lt;/span&gt; &lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; &lt;span style="color: #ff00ff"&gt;MAX&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;SumaPrecios&lt;span style="color: #808080"&gt;)&lt;/span&gt; &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; ListaProductos&lt;span style="color: #808080"&gt;)&lt;/span&gt;&lt;/div&gt;  &lt;p&gt;Este es un ejemplo muy simple de cómo funcionan, aunque a continuación se verá cómo aprovechar más esta nueva característica.&lt;/p&gt;  &lt;p&gt;Existen dos tipos de CTE en SQL Server: los recursivos y lo no recursivos. Con los primeros es posible manejar jerarquías, aunque no con la misma potencia que se propone en el post &lt;a href="http://olapdevelopment.blogspot.com/2008_11_01_archive.html#7388759541650254531"&gt;Gestión de jerarquías en SQL Server(I)&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Mediante los CTE recursivos es posible crear consultas que devuelvan los datos estructurados jerárquicamente, es decir, podemos construir una jerarquía de elementos idpadre-idelemento-nivel a partir de tablas que no contienen esta información directamente. Como más claro se va a ver es en siguiente ejemplo:&lt;/p&gt;  &lt;p&gt;Supongamos que tenemos una tabla con productos que contienen las columnas de IdProducto y otra con la relación con su elemento padre. El nivel es relativamente costoso calcularlo si se realiza de forma tradicional. Por ello, si empleamos una CTE tal como esta&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;WITH&lt;/span&gt; JerarquiaProductos&lt;span style="color: #808080"&gt;(&lt;/span&gt;IdProductoPadre, IdProducto, Nombre, Nivel&lt;span style="color: #808080"&gt;)&lt;/span&gt; &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; IdProductoPadre, IdProducto, NombreProducto, &lt;span style="color: #000"&gt;0&lt;/span&gt; &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; Nivel     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; Productos     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; IdProductoPadre &lt;span style="color: #0000ff"&gt;IS&lt;/span&gt; &lt;span style="color: #808080"&gt;NULL&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;UNION&lt;/span&gt; &lt;span style="color: #808080"&gt;ALL&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; p.&lt;span style="color: #202020"&gt;IdProductoPadre&lt;/span&gt;, p.&lt;span style="color: #202020"&gt;IdProducto&lt;/span&gt;, p.NombreProducto, Nivel &lt;span style="color: #808080"&gt;+&lt;/span&gt; &lt;span style="color: #000"&gt;1&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; Productos p     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;INNER&lt;/span&gt; &lt;span style="color: #808080"&gt;JOIN&lt;/span&gt; JerarquiaProductos j     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #0000ff"&gt;ON&lt;/span&gt; p.&lt;span style="color: #202020"&gt;IdProductoPadre&lt;/span&gt; &lt;span style="color: #808080"&gt;=&lt;/span&gt; j.&lt;span style="color: #202020"&gt;IdProducto&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; IdProductoPadre, IdProducto, Nombre, Nivel     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; JerarquiaProductos&lt;/div&gt;  &lt;p&gt;vamos a obtener los siguientes resultados:&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="0" border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="147"&gt;IdProductoPadre&lt;/td&gt;        &lt;td valign="top" width="109"&gt;IdProducto&lt;/td&gt;        &lt;td valign="top" width="160"&gt;Nombre&lt;/td&gt;        &lt;td valign="top" width="136"&gt;Nivel&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="147"&gt;Null&lt;/td&gt;        &lt;td valign="top" width="109"&gt;1&lt;/td&gt;        &lt;td valign="top" width="160"&gt;Coche&lt;/td&gt;        &lt;td valign="top" width="136"&gt;0&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="147"&gt;1&lt;/td&gt;        &lt;td valign="top" width="109"&gt;2&lt;/td&gt;        &lt;td valign="top" width="160"&gt;Motor&lt;/td&gt;        &lt;td valign="top" width="136"&gt;1&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="147"&gt;1&lt;/td&gt;        &lt;td valign="top" width="109"&gt;3&lt;/td&gt;        &lt;td valign="top" width="160"&gt;Chasis&lt;/td&gt;        &lt;td valign="top" width="136"&gt;1&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="147"&gt;2&lt;/td&gt;        &lt;td valign="top" width="109"&gt;4&lt;/td&gt;        &lt;td valign="top" width="160"&gt;Filtro aceite&lt;/td&gt;        &lt;td valign="top" width="136"&gt;2&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="147"&gt;…&lt;/td&gt;        &lt;td valign="top" width="109"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="top" width="160"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="top" width="136"&gt;&amp;#160;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;En el caso de que nuestra jerarquía disponga de multitud de niveles debemos especificar el parámetro MAXRECURSION con el fin de que no colapsemos el sistema. Su valor puede estar entre 1y 32757.&lt;/p&gt;  &lt;p&gt;Como vemos, esta característica nos permite representar una jerarquía a partir de orígenes que no contienen esta estructura directamente, junto a operaciones simples sobre los elementos de ella. Pero si queremos un poco más, esta técnica se queda corta.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6817090233381397254-4996508575711418275?l=olapdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://olapdevelopment.blogspot.com/feeds/4996508575711418275/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6817090233381397254&amp;postID=4996508575711418275' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6817090233381397254/posts/default/4996508575711418275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6817090233381397254/posts/default/4996508575711418275'/><link rel='alternate' type='text/html' href='http://olapdevelopment.blogspot.com/2008_11_01_archive.html#4996508575711418275' title='Gestión de jerarquías en SQL Server(II) : CTE’s'/><author><name>Oscar</name><uri>http://www.blogger.com/profile/14247779861110707894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6817090233381397254.post-7388759541650254531</id><published>2008-11-05T08:51:00.001+01:00</published><updated>2008-11-07T15:49:30.686+01:00</updated><title type='text'>Gestión de jerarquías en SQL Server(I) : hierarchyid</title><content type='html'>&lt;p&gt;En Microsoft SQL Server 2008 se han introducido mejoras respecto a la versión 2005. Una de ellas es el nuevo tipo de dato llamado hierarchyId. Con este nuevo tipo de dato es posible organizar las entidades jerárquicas de una manera mucho más sencilla. &lt;/p&gt;  &lt;p&gt;HierarchyId no es un tipo propio de SQL Server (como pudiera ser int o varchar), ya que se trata de un tipo del CLR propio del sistema. Por ello, dispone de una serie de funciones (&lt;a href="http://technet.microsoft.com/en-us/library/bb677193.aspx"&gt;http://technet.microsoft.com/en-us/library/bb677193.aspx&lt;/a&gt;) con las que se puede leer de diferentes niveles, obtener un nivel, etc. Tareas estas que eran mucho más complicadas en versiones anteriores de SQL Server. &lt;/p&gt;  &lt;p&gt;Sí, sí. Todo esto está muy bien pero, ¿cómo funciona de verdad?&lt;/p&gt;  &lt;p&gt;En el siguiente ejemplo se crea una tabla y se manejan datos con ella.&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;CREATE&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TABLE&lt;/span&gt; Geografia     &lt;br /&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;elemento hierarchyid &lt;span style="color: #0000ff"&gt;PRIMARY&lt;/span&gt; &lt;span style="color: #0000ff"&gt;KEY&lt;/span&gt; &lt;span style="color: #0000ff"&gt;CLUSTERED&lt;/span&gt;,     &lt;br /&gt;nivel &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; elemento.&lt;span style="color: #202020"&gt;GetLevel&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt; PERSISTED,     &lt;br /&gt;id_elemento &lt;span style="color: #0000ff"&gt;INT&lt;/span&gt; &lt;span style="color: #0000ff"&gt;UNIQUE&lt;/span&gt;,     &lt;br /&gt;nombre_elemento &lt;span style="color: #0000ff"&gt;VARCHAR&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #000"&gt;30&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt; &lt;span style="color: #808080"&gt;NOT&lt;/span&gt; &lt;span style="color: #808080"&gt;NULL&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;&lt;/div&gt;  &lt;p&gt;Como vemos el campo “elemento”, primary key, es de tipo hierarchyid, lo que simplifica el cálculo del campo “nivel”, puede calcularse de manera directa (además para este campo se introduce la palabra clave “PERSISTED” que lo almacena permanentemente en el campo de forma que no se recalcula cada vez que se realiza una consulta sobre la tabla). &lt;/p&gt;  &lt;p&gt;A la hora de insertar datos se realizaría de la siguiente forma&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;INSERT&lt;/span&gt; &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; Municipios &lt;span style="color: #0000ff"&gt;VALUES&lt;/span&gt; &lt;span style="color: #808080"&gt;(&lt;/span&gt;hierarchyid::GetRoot&lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;,&lt;span style="color: #000"&gt;1&lt;/span&gt;,&lt;span style="color: #ff0000"&gt;'España'&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;&lt;/div&gt;  &lt;p&gt;y para otras filas que no sean la raíz&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;DECLARE&lt;/span&gt; @NodoEspana hierarchyid&lt;/div&gt;  &lt;p&gt;Para recuperar el nodo principal podemos usar&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; @NodoEspana &lt;span style="color: #808080"&gt;=&lt;/span&gt;elemento &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; Municipios &lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; id_municipio&lt;span style="color: #808080"&gt;=&lt;/span&gt;&lt;span style="color: #000"&gt;1&lt;/span&gt;&lt;/div&gt;  &lt;p&gt;O también&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; @NodoEspana &lt;span style="color: #808080"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff"&gt;CAST&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #ff0000"&gt;'/'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; hierarchyid&lt;span style="color: #808080"&gt;)&lt;/span&gt;&lt;/div&gt;  &lt;p&gt;Y, ¿Cómo insertamos las filas restantes de la tabla?&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;INSERT&lt;/span&gt; &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; Employees &lt;span style="color: #0000ff"&gt;VALUES&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;@NodoEspana.&lt;span style="color: #202020"&gt;GetDescendant&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #808080"&gt;NULL&lt;/span&gt;, &lt;span style="color: #808080"&gt;NULL&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;,&lt;span style="color: #000"&gt;2&lt;/span&gt;, &lt;span style="color: #ff0000"&gt;'Madrid'&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;&lt;/div&gt;  &lt;br /&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;INSERT&lt;/span&gt; &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; Employees &lt;span style="color: #0000ff"&gt;VALUES&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;@NodoEspana.&lt;span style="color: #202020"&gt;GetDescendant&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #808080"&gt;NULL&lt;/span&gt;, &lt;span style="color: #808080"&gt;NULL&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;,&lt;span style="color: #000"&gt;3&lt;/span&gt;, &lt;span style="color: #ff0000"&gt;'Asturias'&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;&lt;/div&gt;  &lt;p&gt;Para el caso de nodos de nivel 2&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;DECLARE&lt;/span&gt; @NodoMadrid hierarchyid&lt;/div&gt;  &lt;br /&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; @NodoMadrid &lt;span style="color: #808080"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff"&gt;CAST&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #ff0000"&gt;'/1/'&lt;/span&gt; &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; hierarchyid&lt;span style="color: #808080"&gt;)&lt;/span&gt;&lt;/div&gt;  &lt;br /&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;INSERT&lt;/span&gt; &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; Employees &lt;span style="color: #0000ff"&gt;VALUES&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;@NodoMadrid.&lt;span style="color: #202020"&gt;GetDescendant&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #808080"&gt;NULL&lt;/span&gt;, &lt;span style="color: #808080"&gt;NULL&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;,&lt;span style="color: #000"&gt;4&lt;/span&gt;, &lt;span style="color: #ff0000"&gt;'Madrid ciudad'&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;&lt;/div&gt;  &lt;p&gt;O también&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;INSERT&lt;/span&gt; &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; Employees &lt;span style="color: #0000ff"&gt;VALUES&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;@NodoMadrid.&lt;span style="color: #202020"&gt;GetDescendant&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; elemento &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; Geografia &lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; id_elemento&lt;span style="color: #808080"&gt;=&lt;/span&gt;&lt;span style="color: #000"&gt;2&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;, &lt;span style="color: #808080"&gt;NULL&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;,&lt;span style="color: #000"&gt;4&lt;/span&gt;, &lt;span style="color: #ff0000"&gt;'Madrid ciudad'&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt;&lt;/div&gt;  &lt;p&gt;Como vemos, mediante la función GetDescendant podemos insertar filas, siendo los dos parámetros que acepta los niveles donde queremos que inserte el nuevo elemento.&lt;/p&gt;  &lt;p&gt;Y, ¿cómo se muestran y manejan los datos de una consulta?&lt;/p&gt;  &lt;div class="tsql" style="border-right: #d0d0d0 1px solid; border-top: #d0d0d0 1px solid; border-left: #d0d0d0 1px solid; color: #006; border-bottom: #d0d0d0 1px solid; font-family: monospace; background-color: #f0f0f0"&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; elemento.&lt;span style="color: #202020"&gt;ToString&lt;/span&gt;&lt;span style="color: #808080"&gt;(&lt;/span&gt;&lt;span style="color: #808080"&gt;)&lt;/span&gt; &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; Jerarquia,     &lt;br /&gt;elemento &lt;span style="color: #0000ff"&gt;AS&lt;/span&gt; NodoBinario,     &lt;br /&gt;nivel,     &lt;br /&gt;id_elemento,     &lt;br /&gt;nombre_elemento     &lt;br /&gt;&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; Geografia&lt;/div&gt;  &lt;p&gt;Esto nos devuelve los siguientes registros &lt;/p&gt;  &lt;table cellspacing="0" cellpadding="0" border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="115"&gt;         &lt;p&gt;Jerarquia&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;NodoBinario&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;nivel&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;Id_elemento&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;Nombre_elemento&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="115"&gt;         &lt;p&gt;/&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;0x&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;0&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;1&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;España&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="115"&gt;         &lt;p&gt;/1/&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;0x58&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;1&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;2&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;Madrid&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="115"&gt;         &lt;p&gt;/2/&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;0x68&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;1&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;3&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;Asturias&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="115"&gt;         &lt;p&gt;/1/1/&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;0x5AC0&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;2&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;4&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="115"&gt;         &lt;p&gt;Madrid ciudad&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Así, hemos creado un árbol jerárquico con ramas asimétricas, es decir, que no tienen la misma profundidad.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6817090233381397254-7388759541650254531?l=olapdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://olapdevelopment.blogspot.com/feeds/7388759541650254531/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6817090233381397254&amp;postID=7388759541650254531' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6817090233381397254/posts/default/7388759541650254531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6817090233381397254/posts/default/7388759541650254531'/><link rel='alternate' type='text/html' href='http://olapdevelopment.blogspot.com/2008_11_01_archive.html#7388759541650254531' title='Gestión de jerarquías en SQL Server(I) : hierarchyid'/><author><name>Oscar</name><uri>http://www.blogger.com/profile/14247779861110707894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6817090233381397254.post-3635787964956760118</id><published>2008-10-23T15:25:00.005+02:00</published><updated>2008-10-23T17:07:39.662+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bienvenida'/><title type='text'>Bienvenidos</title><content type='html'>&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;Este blog nace con la intención de aportar y difundir conocimiento variado acerca del mundo de Business Intelligence. Para ello se van a tratar diversos temas, pero siempre intentando que sean cosas curiosas y prácticas tanto para expertos como para profanos.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;Así, en los post habrá comparativas entre herramientas diversas, curiosidades, desarrollo de plataformas que extraigan información de ellas, etc. Además no se va a centrar en ningún motor de base de datos en concreto, sino que va a incluir tanto sistemas de gestión de bases de datos de código abierto como privado.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;font-size:85%;"&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;font-size:85%;"&gt;Espero que os sea de gran ayuda, por lo que &lt;strong&gt;estad atentos&lt;/strong&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;font-size:85%;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6817090233381397254-3635787964956760118?l=olapdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://olapdevelopment.blogspot.com/feeds/3635787964956760118/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6817090233381397254&amp;postID=3635787964956760118' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6817090233381397254/posts/default/3635787964956760118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6817090233381397254/posts/default/3635787964956760118'/><link rel='alternate' type='text/html' href='http://olapdevelopment.blogspot.com/2008_10_01_archive.html#3635787964956760118' title='Bienvenidos'/><author><name>Oscar</name><uri>http://www.blogger.com/profile/14247779861110707894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
