sql-server - sp3 - sql server 2005 full
SimulaciĆ³n de CONECTAR POR ANTES de ORACLE en SQL SERVER (3)
¡La respuesta de @Alex Martelli
es genial! Pero funciona solo para un elemento a la vez ( WHERE name = ''Joan''
) Si saca la cláusula WHERE
, la consulta devolverá todas las filas de la raíz juntas ...
Cambié un poco mi situación, por lo que puede mostrar todo el árbol para una mesa.
tabla de definición:
CREATE TABLE [dbo].[mar_categories] (
[category] int IDENTITY(1,1) NOT NULL,
[name] varchar(50) NOT NULL,
[level] int NOT NULL,
[action] int NOT NULL,
[parent] int NULL,
CONSTRAINT [XPK_mar_categories] PRIMARY KEY([category])
)
(el level
es literalmente el nivel de una categoría 0: raíz, 1: primer nivel después de la raíz, ...)
y la consulta:
WITH n(category, name, level, parent, concatenador) AS
(
SELECT category, name, level, parent, ''(''+CONVERT(VARCHAR (MAX), category)+'' - ''+CONVERT(VARCHAR (MAX), level)+'')'' as concatenador
FROM mar_categories
WHERE parent is null
UNION ALL
SELECT m.category, m.name, m.level, m.parent, n.concatenador+'' * (''+CONVERT (VARCHAR (MAX), case when ISNULL(m.parent, 0) = 0 then 0 else m.category END)+'' - ''+CONVERT(VARCHAR (MAX), m.level)+'')'' as concatenador
FROM mar_categories as m, n
WHERE n.category = m.parent
)
SELECT distinct * FROM n ORDER BY concatenador asc
(No necesita concatenar el campo de level
, solo lo hice para que sea más legible)
la respuesta para esta consulta debería ser algo como:
¡Espero que esto ayude a alguien!
ahora, me pregunto cómo hacer esto en MySQL ... ^^
Me gustaría obtener la funcionalidad de CONNECT BY ANUAL of ORACLE en SQL SERVER 2000/2005/2008?
por favor, ayúdame
No he usado Connect antes, pero una búsqueda rápida muestra que se usa para estructuras de árbol. En SQL Server, utiliza expresiones de tabla comunes para obtener una funcionalidad similar.
La forma estándar de SQL para implementar consultas recursivas, implementada, por ejemplo, por IBM DB2 y SQL Server , es la cláusula WITH
. Consulte ibm.com/developerworks/db2/library/techarticle/dm-0510rielau para ver un ejemplo de traducción de CONNECT BY
en un WITH
( CTE técnicamente recursivo ): el ejemplo es para DB2, pero creo que también funcionará en SQL Server.
Editar: aparentemente el querant original requiere un ejemplo específico, aquí hay uno del sitio de IBM cuya URL ya di. Dada una mesa:
CREATE TABLE emp(empid INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(10),
salary DECIMAL(9, 2),
mgrid INTEGER);
donde mgrid
referencia al mgrid
un empleado, la tarea es obtener los nombres de todos los que informan directa o indirectamente a Joan
. En Oracle, eso es un simple CONNECT
:
SELECT name
FROM emp
START WITH name = ''Joan''
CONNECT BY PRIOR empid = mgrid
En SQL Server, IBM DB2 o PostgreSQL 8.4 (así como en el estándar SQL, por lo que vale ;-), la solución perfectamente equivalente es, en cambio, una consulta recursiva (sintaxis más compleja, pero, en realidad, aún más potencia y flexibilidad) )
WITH n(empid, name) AS
(SELECT empid, name
FROM emp
WHERE name = ''Joan''
UNION ALL
SELECT nplus1.empid, nplus1.name
FROM emp as nplus1, n
WHERE n.empid = nplus1.mgrid)
SELECT name FROM n
La cláusula START WITH
Oracle se convierte en el primer SELECT
anidado, el caso base de la recursión, para ser UNION
ed con la parte recursiva que es simplemente otro SELECT
.
El sabor específico de SQL Server está, por supuesto, documentado en MSDN , que también brinda pautas y limitaciones para usar esta palabra clave, así como varios ejemplos.