IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

[IB 6, FireBird 1.5] SKIP dans les sous-requêtes


Sujet :

Langage SQL

  1. #1
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut [IB 6, FireBird 1.5] SKIP dans les sous-requêtes
    Bonjour tout le monde,

    J'utilise une base Interbase 6 connectée à un serveur sous Firebird 1.5

    En voulant aider un utilisateur de ce forum j'ai découvert que l'équivalent de la commande LIMIT de la norme SQL est SKIP sous Interbase / Firebird.

    Ceci dit, je n'obtiens pas le résultat attendu lorsque j'utilise cette commande dans une sous-requête ; ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    CREATE TABLE TMP (
        RECID INTEGER,
        FL_PRENOM VARCHAR(25),
        FL_NOM VARCHAR(25)
    );
     
    INSERT INTO TMP VALUES (15, 'Jean', 'Dupont');
    INSERT INTO TMP VALUES (18, 'Romain', 'Dupont');
    INSERT INTO TMP VALUES (20, 'Severine', 'Dupont');
    INSERT INTO TMP VALUES (16, 'Florent', 'Durand');
    INSERT INTO TMP VALUES (17, 'Sylvain', 'Pigier');
    INSERT INTO TMP VALUES (19, 'Amelie', 'Pigier');
    INSERT INTO TMP VALUES (21, 'Pascal', 'Pigier');
    INSERT INTO TMP VALUES (22, 'Stephane', 'Pigier');
    INSERT INTO TMP VALUES (23, 'Myriame', 'Durand');
     
    SELECT T1.*
    FROM TMP T1
    WHERE EXISTS ( SELECT FIRST 2 T2.*
                   FROM TMP T2
                   WHERE T2.FL_NOM = T1.FL_NOM
                   ORDER BY T2.FL_NOM, T2.FL_PRENOM DESC )
    ORDER BY T1.FL_NOM, T1.FL_PRENOM DESC;
    Cette dernière requête me retourne exactement le même jeu de données (elle n'effectue aucun filtre) que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM TMP
    ORDER BY FL_NOM, FL_PRENOM DESC;
    Où ai-je commis une erreur ?
    Merci d'avance.
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  2. #2
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    WHERE EXISTS renvoie 'TRUE' dès que le SELECT renvoie une ligne, et comme il y a toujours une ligne qui vérifie T2.FL_NOM = T1.FL_NOM, tu obtiens le même résultat que sans aucune condition.

    Je ne suis pas certain que LIMIT soit dans la norme SQL.
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  3. #3
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Salut Médiat,

    Citation Envoyé par Médiat
    WHERE EXISTS renvoie 'TRUE' dès que le SELECT renvoie une ligne, et comme il y a toujours une ligne qui vérifie T2.FL_NOM = T1.FL_NOM, tu obtiens le même résultat que sans aucune condition.
    D'accord, donc la requête suivante devrait effectuer le filtre que je désire, malheureusement ça ne change rien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT T1.*
    FROM TMP T1
    WHERE T1.RECID IN ( SELECT FIRST 2 T2.RECID
                        FROM TMP T2
                        WHERE T2.FL_NOM = T1.FL_NOM
                        ORDER BY T2.FL_NOM, T2.FL_PRENOM DESC )
    ORDER BY T1.FL_NOM, T1.FL_PRENOM DESC;
    Je ne suis pas certain que LIMIT soit dans la norme SQL.
    justement j'ai trouvé ce tableau présentant toutes les fonctions dans SQL et je me demandais quelles sont les fonctions incluses dans la norme et celles qui ne le sont pas ?

    PS : entre nous tu es insomniaque pour répondre à toute heure ?
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  4. #4
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    1) Effectivement cela devrait marcher ..
    Que donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT FIRST 2 T2.RECID 
    FROM TMP T2 
    ORDER BY T2.FL_NOM, T2.FL_PRENOM DESC
    2) Dans le tableau que tu donnes en lien il y a une colonne Norme SQL, tu y verras qu'il n'y a aucun mot clé dans la norme qui corresponde à LIMIT

    3) Tu pourrais faire la même chose avec une jointure et un GROUP BY de façon totalement normée.

    4) Non je ne suis pas un vrai insomniaque, mais je peux ne dormir que très peu et j'en profite
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  5. #5
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    1) j'ai déjà pensé à testé cette requête et elle applique bien le filtre désiré => elle retourne : 2 enregistrements (20 et 18)

    2) j'ai encore fait très fort, la prochaine j'ouvrirai les

    3) euh... je vois parfaitement ce que tu veux dire mais je ne vois pas du tout comment procéder : tu ferais comment ?

    4) le futur t'appartient

    Merci encore.
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  6. #6
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Pas testé...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT T1.FL_NOM, T1.FL_PRENOM
    FROM TMP T1 INNER JOIN TMP T2 ON T2.FL_NOM = T1.FL_NOM AND T1.FL_PRENOM >= T2.FL_PRENOM 
    GROUP BY T1.FL_NOM, T1.FL_PRENOM
    HAVING COUNT(*) <= 2
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  7. #7
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Merci de ta réponse mais ça ne donne pas le résultat que je veux.

    Et j'ai beau réfléchir je ne comprends toujours pas comment on peut compenser la commande LIMITE (ou ses équivalents) par une jointure et un GROUP BY.

    En fait, dans le jeu d'essai que j'ai donné on ne peut pas faire un regroupement en stipulant que le COUNT(*) du GROUP BY soit <= 2 car on veut les 2 enregistrements ayant COUNT(*) maximal.

    Ex : pour le nom 'Dupont', on a :
    FL_PRENOM / COUNT(*)
    Jean / 1
    Romain / 2
    Severine / 3
    Il faut donc retourner Severine et Romain car ce sont les 2 enregistrements ayant COUNT(*) maximal.

    En revanche : pour le nom 'Durand', on a :
    FL_PRENOM / COUNT(*)
    Florent / 1
    Myriame / 2
    Il faut retourner Myriame puis Florent.

    Bref, je ne vois vraiment pas comment faire sans LIMITE et je n'arrive pas non plus à appliquer correctement cette commande...
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  8. #8
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Je ne peux pas essayer avant ce soir, mais en inversant la comparaison cela devrait marcher, et rien dn'interdit d'ajouter un ORDER BY :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT T1.FL_NOM, T1.FL_PRENOM 
    FROM TMP T1 INNER JOIN TMP T2 ON T2.FL_NOM = T1.FL_NOM AND T1.FL_PRENOM <= T2.FL_PRENOM 
    GROUP BY T1.FL_NOM, T1.FL_PRENOM 
    HAVING COUNT(*) <= 2
    ORDER BY T1.FL_NOM, T1.FL_PRENOM DESC
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  9. #9
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Ahhhhhhhh d'accord.

    Je viens de comprendre la logique et effectivement ça marche.
    Nan vraiment ton raisonnement est impeccable
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/10/2013, 12h09
  2. Perte de référence dans les sous-requêtes
    Par stephane.combes dans le forum Requêtes
    Réponses: 8
    Dernier message: 10/06/2013, 11h38
  3. [visibilité] Nouveaux Messages dans les sous Forum
    Par Maxoo dans le forum Evolutions du club
    Réponses: 13
    Dernier message: 03/07/2006, 10h35
  4. Calcul dans les sous-formulaires
    Par rafa55 dans le forum Access
    Réponses: 3
    Dernier message: 21/06/2006, 10h37
  5. se ballader dans les sous repertoires
    Par Krispy dans le forum Langage
    Réponses: 1
    Dernier message: 30/03/2006, 15h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo