7
votes

Existe-t-il une limite de nidification pour les sous-requêtes corrélées dans certaines versions d'Oracle?

Voici le code qui vous aidera à comprendre ma question: xxx pré>

Veuillez considérer le numéro 10 à la fin de la requête pour être un paramètre. En d'autres termes, cette valeur est simplement codée en dur dans cet exemple; Cela changerait en fonction de l'entrée. P>

Ma question est la suivante: pourquoi est-ce que je reçois l'erreur p> xxx pré>

pour la sous-requête imbriquée et corrélée? Y a-t-il une sorte de limite de nidification? Cette sous-requête doit être couru pour chaque ligne du Resultint car les résultats changeront en fonction du contenu_id, qui peut être différent pour chaque ligne. Comment puis-je accomplir cela avec Oracle? P>

Pas que j'essaie de créer une discussion de SQL Server VS Oracle, mais je viens d'un arrière-plan SQL Server et je voudrais souligner que ce qui suit, Query équivalent fonctionne bien sur SQL Server: P>

create table con ( content_id int);
create table mat ( material_id int, content_id int, resolution int, file_location varchar(50));
create table con_groups (content_group_id int, content_id int);

insert into con values (99);
insert into mat values (1, 99, 7, 'C:\foo.jpg');
insert into mat values (2, 99, 2, '\\server\xyz.mov');
insert into mat values (3, 99, 5, '\\server2\xyz.wav');
insert into con values (100);
insert into mat values (4, 100, 5, 'C:\bar.png');
insert into mat values (5, 100, 3, '\\server\xyz.mov');
insert into mat values (6, 100, 7, '\\server2\xyz.wav');

insert into con_groups values (10, 99);
insert into con_groups values (10, 100);

SELECT m.material_id,
       (SELECT file_location 
          FROM (SELECT TOP 1 file_location
                  FROM mat
                 WHERE mat.content_id = m.content_id
              ORDER BY resolution DESC) special_mats_for_this_content            
               ) special_mat_file_location                                     
  FROM mat m
 WHERE m.material_id IN (select material_id 
                           from mat
                     inner join con on con.content_id = mat.content_id
                     inner join con_groups on con_groups.content_id = con.content_id
                          where con_groups.content_group_id = 10);


2 commentaires

Cette requête fonctionne dans Oracle 12.2. Je n'ai pas 12,1 à tester avec et je ne trouve pas la limite de la documentation, mais certaines limitations sont supprimées en 12C.


Bon à savoir! Ajout de la version Info La question. J'utilisais Oracle 9i à l'époque.


3 Réponses :


8
votes

Les versions récentes d'Oracle n'ont pas de limite, mais la plupart des versions plus anciennes d'Oracle ont une limite de nidification de 1 code> de niveau profond.

Ceci fonctionne sur toutes les versions: p>

SELECT  *
FROM    (
        SELECT  m.material_id, ROW_NUMBER() OVER (PARTITION BY content_id ORDER BY resolution DESC) AS rn
        FROM    mat m
        WHERE   m.material_id IN
                (
                SELECT  con.content_id
                FROM    con_groups
                JOIN    con
                ON      con.content_id = con_groups.content_id
                WHERE   con_groups.content_group_id = 10
                )
        )
WHERE   rn = 1


4 commentaires

N'est-ce pas une limitation d'Oracle? Je pensais que Oracle était censé être supérieur à SQL Server, de telles tables temporaires, etc. ne sont jamais nécessaires. Quelle est une autre façon que je puisse accomplir ma requête?


@Nate: Les tables temporaires peuvent être construites dans Oracle Jsut. En fait, SQL Server (à partir de 2005 ) est supérieur à oracle (à partir de 10g ) en termes de Effectuer des plans d'exécution. Le verrouillage, les langues procédurales et les curseurs sont une histoire différente.


Vous pouvez nier jusqu'à 255 niveaux de sous-requêtes dans la clause OLS de Oracle 9i: download.oracle.com/docs/cd/b10501_01/server.920/a96540/...


@Rexem: @op a posé des questions sur corrélation sous-requêtes. Vous ne pouvez pas les nicher. La sous-requête imbriquée plus d'un niveau de profondeur ne verra pas les colonnes de la requête extérieure.



1
votes

Quassnoi répondit à ma question à propos de la nidification et a fait un excellent appel en suggérant des fonctions analytiques de fenêtre. Voici la requête exacte dont j'ai besoin: xxx

merci!


0 commentaires

3
votes

@Quassnoi C'était le cas dans Oracle 9. De Oracle 10 ...

de Référence SQL de la base de données Oracle 10G version 1 (10.1) Oracle effectue une sous-requête corrélée lorsqu'une sous-requête imbriquée fait référence à une colonne d'un tableau faisant référence à une déclaration parent n'importe quel nombre de niveaux au-dessus de la sous-requête

de version de référence Oracle9i SQL 2 (9.2) Oracle effectue une sous-requête corrélée lorsque la sous-requête fait référence à une colonne d'une table mentionnée dans la déclaration parent .

Une sous-requête dans la où la clause d'une instruction SELECT est également appelée sous-requête imbriquée. Vous pouvez nier jusqu'à 255 niveaux de sous-requêtes dans la sous-requête imbriquée.

Je ne pense pas que cela fonctionne si vous avez quelque chose comme SELECT * à partir de (sélectionnez * à partir de (.... ....))))

Juste Sélectionnez * à partir d'alias de nom de table où Colname = (sélectionnez * à partir de quelque part où Somecol = (Sélectionnez * à partir de quelque chose de x où x.Id = alias.col))

Vérifiez http://forums.oracle.com/forums/thread .jspa? threadid = 378604


0 commentaires