Pourquoi se CONNECTER PAR NIVEAU sur une table retour lignes supplémentaires?
À l'aide de CONNECTER PAR NIVEAU semble renvoyer trop de lignes lorsqu'il est effectué sur une table. Quelle est la logique derrière ce qui se passe?
En supposant que le tableau suivant:
create table a ( id number );
insert into a values (1);
insert into a values (2);
insert into a values (3);
Cette requête renvoie les 12 lignes (SQL Violon).
select id, level as lvl
from a
connect by level <= 2
order by id, level
Une ligne pour chaque tableau avec la valeur de la colonne LVL 1 et trois pour chaque table où la colonne est LVL 2, c'est à dire:
ID | LVL ---+----- 1 | 1 1 | 2 1 | 2 1 | 2 2 | 1 2 | 2 2 | 2 2 | 2 3 | 1 3 | 2 3 | 2 3 | 2
C'est équivalent à cette requête, qui renvoie les mêmes résultats.
select id, level as lvl
from dual
cross join a
connect by level <= 2
order by id, level
Je ne comprends pas pourquoi ces requêtes de 12 lignes ou pourquoi il ya trois rangées où LVL 2 et un seul où LVL est de 1 pour chaque valeur de la colonne ID.
En augmentant le nombre de niveaux qui sont "connectés" à 3 retourne 13 lignes pour chaque valeur de l'ID. 1 où est LVL 1, 3, où le LVL 2 et 9 où est LVL 3. Cela semble suggérer que le nombre de lignes retournées sont le nombre de lignes dans Un tableau à la puissance de la valeur de LVL de moins 1.
J'aurais cependant que ces requêtes sera la même que la suivante, ce qui renvoie
6 lignes
select id, lvl
from ( select level as lvl
from dual
connect by level <= 2
)
cross join a
order by id, lvl
La la documentation n'est pas particulièrement clair, pour moi, dans l'explication de ce qui devrait se produire. Ce qui se passe avec ces pouvoirs, et pourquoi ne sont pas les deux premières requêtes le même que le troisième?
OriginalL'auteur Ben | 2012-11-24
Vous devez vous connecter pour publier un commentaire.
Dans la première requête, vous vous connectez par le niveau.
Donc, si le niveau <= 1, vous obtenez tous les enregistrements 1 fois. Si le niveau <= 2, puis vous obtenez à chaque niveau de 1 heure (pour le niveau 1) + N fois (où N est le nombre d'enregistrements dans la table). C'est comme de la croix de rejoindre, parce que vous êtes juste ramasser tous les enregistrements de la table jusqu'à ce que le niveau est atteint, sans avoir d'autres conditions à la limite de la suite. Pour le niveau <= 3, ce qui est fait à nouveau pour chacun de ces résultats.
Donc, pour 3 enregistrements:
Ce n'est pas vraiment une jointure croisée. Une jointure croisée ne renvoie les enregistrements qui ont un niveau 2 dans ce résultat de la requête, alors qu'avec ce connecter, vous obtenez les enregistrements ayant le niveau 1 ainsi que les enregistrements ayant le niveau 2, ce qui entraîne dans les 3 + 3*3 au lieu de simplement 3*3 record.
OriginalL'auteur
Quand
connect by
est utilisé sansstart with
clause etprior
de l'opérateur, il n'y a pas de restriction sur l'adhésion à des enfants de ligne à une ligne parent. Et ce que l'Oracle ne dans cette situation, il renvoie tous les possibles de la hiérarchie des permutations en connectant une ligne pour chaque ligne de niveau supérieur.sys_connect_by_path()
<- ce mot-clé a tout expliqué. Un de la meilleure réponse à cette question (pas seulement dans cette rubrique).OriginalL'auteur
vous êtes à comparer des pommes à des oranges lors de la comparaison de la requête finale pour les autres que le NIVEAU est isolé dans celui de la 1 rangée de double de la table.
permet de considérer cette requête:
ce que dit est, commencer avec l'ensemble de la table (select * from un). ensuite, pour chaque ligne retournée à connecter cette ligne à la ligne avant. comme vous n'avez pas défini une jointure dans la connexion, ce qui est en fait un Cartésien rejoindre, de sorte que lorsque vous avez 3 lignes de (1,2,3) 1 joint 2, 1->3, 2->1, 2->3, 3->1 et 3->2 et ils ont également se joindre à eux 1->1,2->2 et 3->3. ces jointures sont de niveau=2. nous avons donc 9 rejoint là-bas, qui est pourquoi vous obtenez 12 lignes (3 original "niveau 1" lignes plus Cartésiens set).
de sorte que le nombre de lignes de sortie = nombre de lignes + (nombre de lignes^2)
dans la dernière requête de vous isoler niveau à ce
qui, bien sûr, renvoie 2 lignes. c'est alors cartesianed à l'origine de 3 lignes, donnant à 6 lignes en sortie.
OriginalL'auteur
Vous pouvez utiliser la technique ci-dessous pour résoudre ce problème:
OriginalL'auteur