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

SQL Firebird Discussion :

Syntaxe du IN avec plusieurs colonnes


Sujet :

SQL Firebird

  1. #1
    Membre expérimenté
    Avatar de giminik
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    303
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 303
    Par défaut Syntaxe du IN avec plusieurs colonnes
    Bonjour à tous,
    Je cherche à exécuter une requête de ce type : (Il s'agit juste d'un exemple pour montrer la syntaxe que je recherche)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT b1.champ1
    FROM base b1
    WHERE (b1.champ2, b1.champ3) IN
    (
    SELECT DISTINCT b2.champ2, b2.champ3
    FROM base b2
    WHERE b2.id = 5
    )
    Je sais que sous Oracle on peut utiliser un IN sur plusieurs colonnes, je voudrais savoir s'il est possible avec Firebird de faire la même chose. (Cette syntaxe génère une erreur sous Firebird.)

    J'ai bien effectué une recherche mais aucuns résultat...
    Merci d'avance pour vos réponses.

  2. #2
    Membre Expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Par défaut
    la réponse est non
    mais si tu en disais plus on trouvera surement une solution satisfaisante

  3. #3
    Membre expérimenté
    Avatar de giminik
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    303
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 303
    Par défaut
    Bon, ça ne m'arrange pas du tout, du coup

    Voici la structure simplifiée de la table sur laquelle je suis en train de travailler :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE NEW_DIAGNOSTIC(
        ID INTEGER,
        CREATIONDATE DATE NOT NULL,
        CREATIONTIME TIME NOT NULL,
        PATIENT_ID INTEGER NOT NULL,
        DIAGNOSTIC_ID INTEGER NOT NULL,
        CONSTRAINT NEW_DIAGNOSTIC_PK PRIMARY KEY(ID),
        CONSTRAINT NEW_DIAGNOSTIC_PATIENT_FK FOREIGN KEY(PATIENT_ID) REFERENCES PATIENT(ID),
        CONSTRAINT NEW_DIAGNOSTIC_DIAGNOSTIC_FK FOREIGN KEY(DIAGNOSTIC_ID) REFERENCES DIAGNOSTIC(ID)
    );
    Et voici mes données d'entrées :

    ID CREATIONDATE CREATIONTIME DIAGNOSTIC_ID PATIENT_ID
    -- ------------ ------------ ------------- ----------
    1 08.08.2008 12:57:10.609 3 1
    2 08.08.2008 13:09:20.843 1 2
    3 08.08.2008 13:11:20.171 3 3
    4 08.08.2008 13:14:01.359 5 4
    5 08.08.2008 13:17:15.343 6 5
    6 08.08.2008 13:22:27.234 5 6
    7 08.08.2008 13:27:34.968 1 7
    8 08.08.2008 16:35:02.780 1 8
    9 08.08.2008 13:39:09.796 2 9
    10 19.08.2008 14:12:20.000 1 8
    11 19.08.2008 14:38:24.187 1 8
    12 19.08.2008 14:39:35.609 3 8
    Ce que je dois faire, c'est récupérer les enregistrements pour un patient (8 pour mon exemple). Ca devient donc avec un simple WHERE :
    ID CREATIONDATE CREATIONTIME DIAGNOSTIC_ID PATIENT_ID
    -- ------------ ------------ ------------- ----------
    8 08.08.2008 16:35:02.780 1 8
    10 19.08.2008 14:12:20.000 1 8
    11 19.08.2008 14:38:24.187 1 8
    12 19.08.2008 14:39:35.609 3 8
    À partir de là, je dois récupérer les ID des lignes contenant les couples DIAGNOSTIC_ID et PATIENT_ID qui ont la date/heure de création la plus ancienne.

    Donc dans mon cas, je devrais avoir les ID 12 (puisqu'il n'y en à qu'un seul pour le couple 3/8) et 8 pour le couple 1/8 car c'est le plus ancien.

    Donc, la clause IN avec plusieurs colonnes m'aurait vraiment bien aidé pour faire ça, du coup, je ne sais pas trop comment m'y prendre. J'hésite même à traiter directement les données en C++...

    Si vous avez une piste ou solution je suis preneur.

  4. #4
    Membre Expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Par défaut
    pardon ? avec le IN oracle ça s'écrirait comment ?
    pour être sûr de bien comprendre
    parce qu'à priori voilà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    WITH 
    N2 (PATIENT_ID,DIAGNOSTIC_ID,CREATIONDATE,CREATIONTIME) 
    AS 
    (SELECT N1.PATIENT_ID,N1.DIAGNOSTIC_ID ,MIN(N1.CREATIONDATE),MIN(N1.CREATIONTIME) 
    FROM NEW_DIAGNOSTIC N1  
    WHERE N1.PATIENT_ID=8 
    GROUP BY N1.PATIENT_ID ,N1.DIAGNOSTIC_ID)
     
    SELECT ND.ID FROM NEW_DIAGNOSTIC ND 
    JOIN N2 ON ( N2.PATIENT_ID=ND.PATIENT_ID AND N2.DIAGNOSTIC_ID=ND.DIAGNOSTIC_ID
    AND N2.CREATIONDATE=ND.CREATIONDATE )
    deuxième solution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT ND.ID FROM NEW_DIAGNOSTIC ND 
    JOIN 
    (SELECT N1.PATIENT_ID,N1.DIAGNOSTIC_ID ,MIN(N1.CREATIONDATE) CREATIONDATE,MIN(N1.CREATIONTIME) CREATIONTIME
    FROM NEW_DIAGNOSTIC N1  
    WHERE N1.PATIENT_ID=8 
    GROUP BY N1.PATIENT_ID ,N1.DIAGNOSTIC_ID) N2 
    ON ( N2.PATIENT_ID=ND.PATIENT_ID AND N2.DIAGNOSTIC_ID=ND.DIAGNOSTIC_ID
    AND N2.CREATIONDATE=ND.CREATIONDATE )

  5. #5
    Membre expérimenté
    Avatar de giminik
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    303
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 303
    Par défaut
    Bon, ça fait un moment que je n'ai pas fait de SQL, donc ce n'est certainement pas optimisé ce que j'aurais fait, mais j'aurais eu un début de piste comme ceci :
    (je n'y ai pas trop réfléchi puisque j'ai eu tout de suite le problème avec le IN).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT id, MIN(creationdate)
    FROM new_diagnostic
    WHERE patient_id = 8
    AND (diagnostic_id, patient_id) IN (
    SELECT DISTINCT diagnostic_id, patient_id
    FROM new_diagnostic
    WHERE patient_id = 8
    )
    GROUP BY id;
    J'aurais fait ceci, je ne sais pas si c'est juste puisque je ne peux pas tester .

    Merci pour ton aide, la seconde requête fonctionne super, la première, il y a une erreur de syntaxe à la première ligne. Je vais chercher pour voir comment fonctionne le WITH, cette fonction a l'air intéressante.

    Petite question subsidiaire :
    Avec la seconde requête :
    MIN(N1.CREATIONDATE), MIN(N1.CREATIONTIME)
    Est-on certain que le champ CREATIONDATE et CREATIONTIME proviennent bien de la même ligne ?

  6. #6
    Membre Expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Par défaut
    Le WITH a été introduit dans la version Firebird 2.1 (Common Table Expressions : http://www.firebirdsql.org/rlsnotesh...ml#rnfb210-cte)

    et pardon oui, il est préférable de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT ND.ID FROM NEW_DIAGNOSTIC ND 
    JOIN 
    (SELECT N1.PATIENT_ID,N1.DIAGNOSTIC_ID ,MIN(CAST(N1.CREATIONDATE||' '||N1.CREATIONTIME AS TIMESTAMP)) CREATIONDATETIME
    FROM NEW_DIAGNOSTIC N1  
    WHERE N1.PATIENT_ID=8 
    GROUP BY N1.PATIENT_ID ,N1.DIAGNOSTIC_ID) N2 
    ON ( N2.PATIENT_ID=ND.PATIENT_ID AND N2.DIAGNOSTIC_ID=ND.DIAGNOSTIC_ID
    AND N2.CREATIONDATETIME=(CAST(ND.CREATIONDATE||' '||ND.CREATIONTIME AS TIMESTAMP)) )
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    WITH 
    N2 (PATIENT_ID,DIAGNOSTIC_ID,CREATIONDATETIME) 
    AS 
    (SELECT N1.PATIENT_ID,N1.DIAGNOSTIC_ID ,MIN(CAST(N1.CREATIONDATE||' '||N1.CREATIONTIME AS TIMESTAMP)) 
    FROM NEW_DIAGNOSTIC N1  
    WHERE N1.PATIENT_ID=8 
    GROUP BY N1.PATIENT_ID ,N1.DIAGNOSTIC_ID)
     
    SELECT ND.ID FROM NEW_DIAGNOSTIC ND 
    JOIN N2 ON ( N2.PATIENT_ID=ND.PATIENT_ID AND N2.DIAGNOSTIC_ID=ND.DIAGNOSTIC_ID
    AND N2.CREATIONDATETIME=(CAST(ND.CREATIONDATE||' '||ND.CREATIONTIME AS TIMESTAMP)) )

  7. #7
    Membre expérimenté
    Avatar de giminik
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    303
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 303
    Par défaut
    Alors là, merci !
    Si j'avais su qu'on pouvais convertir des dates + heures en timestamp, ça m'aurait bien aidé, je vais la noter quelque part cette fonction.
    Merci beaucoup

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

Discussions similaires

  1. [ComboBox] Combobox avec plusieurs colonnes
    Par madica dans le forum Windows Forms
    Réponses: 6
    Dernier message: 15/01/2007, 11h25
  2. Combo avec plusieurs colonnes (layout?)
    Par spirodeau dans le forum Struts 1
    Réponses: 5
    Dernier message: 04/08/2006, 08h22
  3. vba, listbox avec plusieur colonne
    Par morgan47 dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 20/06/2006, 18h35
  4. liste deroulante avec plusieurs colonnes?
    Par zorba49 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 8
    Dernier message: 16/06/2006, 12h08
  5. Réponses: 1
    Dernier message: 04/05/2005, 11h43

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