sql - solucion - ¿Cómo recuerdo qué camino debe tomar PRIOR en las consultas CONNECT BY?
provider: named pipes provider, error: 40-could not open a connection to sql server (2)
Piense en el orden en que se van a seleccionar los registros: la columna de enlace de cada registro debe coincidir con la columna de enlace hacia adelante en el registro ANTERIOR seleccionado.
Tengo un terrible recuerdo. Cada vez que hago una consulta CONNECT BY en Oracle, y me refiero a todas las veces, tengo que pensar mucho y, por lo general, a través del método de prueba y error, sobre qué argumento debe ir el PRIOR.
No sé por qué no recuerdo, pero no lo sé.
¿Alguien tiene una memoria mnemotécnica útil así que siempre lo recuerdo?
Por ejemplo:
Para bajar un árbol desde un nodo, obviamente tuve que buscar esto :), haces algo como:
select
*
from
node
connect by
prior node_id = parent_node_id
start with
node_id = 1
Entonces, empiezo con un node_id
de 1 (la parte superior de la rama) y la consulta busca todos los nodos donde parent_node_id
= 1 y luego itera hacia la parte inferior del árbol.
Para subir al árbol, el anterior va al padre:
select
*
from
node
connect by
node_id = prior parent_node_id
start with
node_id = 10
Así que comenzando en algún lugar de una rama ( node_id = 10
en este caso) Oracle primero obtiene todos los nodos donde parent_node_id
es el mismo para el que node_id
es 10.
EDITAR : Todavía me sale mal, así que pensé en agregar una edición esclarecedora para ampliar la respuesta aceptada. Así es como la recuerdo ahora:
select
*
from
node
connect by
prior node_id = parent_node_id
start with
node_id = 1
La versión en "idioma inglés" de este SQL ahora leo como ...
En NODO, comenzando con la fila en la que
node_id = 1
, la siguiente fila seleccionada tiene suparent_node_id
igual anode_id
de la fila anterior (anterior).
EDITAR : Quassnoi hace una gran observación: el orden en que escribe el SQL hace las cosas mucho más fáciles.
select
*
from
node
start with
node_id = 1
connect by
parent_node_id = prior node_id
Esto me parece mucho más claro: el "inicio con" da la primera fila seleccionada y el "conectar con" da la (s) siguiente (s) fila (s) - en este caso los hijos de node_id = 1.
Siempre trato de poner las expresiones en JOIN
en el siguiente orden:
joined.column = leading.column
Esta consulta:
SELECT t.value, d.name
FROM transactions t
JOIN
dimensions d
ON d.id = t.dimension
se puede tratar como "para cada transacción, encuentre el nombre de dimensión correspondiente" o "para cada dimensión, encuentre todos los valores de transacción correspondientes".
Entonces, si busco una transacción determinada, pongo las expresiones en el siguiente orden:
SELECT t.value, d.name
FROM transactions t
JOIN
dimensions d
ON d.id = t.dimension
WHERE t.id = :myid
, y si busco una dimensión, entonces:
SELECT t.value, d.name
FROM dimensions d
JOIN
transactions t
ON t.dimension = d.id
WHERE d.id = :otherid
La primera consulta probablemente use escaneos de índice primero en (t.id)
, luego en ( d.id
), mientras que el último usará escaneos de índice primero en (d.id)
, luego en (t.dimension)
, y puede verlo fácilmente en la consulta en sí: los campos buscados están a la izquierda.
Las tablas de conducción y conducidas pueden no ser tan obvias en un JOIN
, pero es tan claro como una campana para una consulta CONNECT BY
: la fila PRIOR
está conduciendo, la no PRIOR
está activada.
Es por eso que esta consulta:
SELECT *
FROM hierarchy
START WITH
id = :root
CONNECT BY
parent = PRIOR id
significa "buscar todas las filas cuyo parent
es un id
determinado". Esta consulta crea una jerarquía.
Esto se puede tratar de esta manera:
connect_by(row) {
add_to_rowset(row);
/* parent = PRIOR id */
/* PRIOR id is an rvalue */
index_on_parent.searchKey = row->id;
foreach child_row in index_on_parent.search {
connect_by(child_row);
}
}
Y esta consulta:
SELECT *
FROM hierarchy
START WITH
id = :leaf
CONNECT BY
id = PRIOR parent
significa "encontrar las filas cuyo id
es un parent
dado". Esta consulta construye una cadena de ancestros.
Siempre ponga PRIOR
en la parte derecha de la expresión.
Piense en la PRIOR column
como una constante, todas sus filas serán buscadas.