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 :

Récuperer le premier tuple ?


Sujet :

SQL Firebird

  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 050
    Points : 40 982
    Points
    40 982
    Billets dans le blog
    62
    Par défaut Récuperer le premier tuple ?
    J'ai deux tables (simplifiées)

    MATIERES
    CODE_MATIERE
    LIBELLE

    FOURNIPAR
    CODE_MATIERE
    CODE_FOURNISSEUR
    PRINCIPAL (O/N)
    relation : 1 / (0,n)

    je voudrais obtenir une liste des matières avec leur premier fournisseur , de préférences le principal (il devrait y en a toujours un et un seul mais ce serait trop beau !!)

    un jeu d'essai
    MATIERES
    1,NUBUCK
    2,VEAU
    3,ALCANTARA
    4,ETIQUETTE

    FOURNIPAR
    1,0001,O
    1,0002,N
    2,0002,O
    3,0003,N //<-- le fournisseur principal a disparu, ou il n'y en a jamais eu
    Je voudrais obtenir
    CODE_MATIERE,LIBELLE,FOURNISSEUR
    1,NUBUCK,0001
    2,VEAU,0002
    3,ALCANTARA,0003
    4,ETIQUETTE,null
    Comment faire ? je sèche
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 050
    Points : 40 982
    Points
    40 982
    Billets dans le blog
    62
    Par défaut Y aurait-il une manière plus 'élégante'
    Après bien des erreurs de syntaxe j'ai trouvé une solution mais la première partie (la CTE) ne pourrait-elle pas être améliorée ? voir remaniée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    WITH F AS (SELECT R.MATIERE,(SELECT FIRST 1 M.CODE_FOURNISSEUR FROM FOURNIPAR M WHERE M.MATIERE=R.MATIERE ORDER BY M.MATIERE,M.PRINCIPAL DESC) AS FOURNISSEUR
    FROM MATFRN R
    )
     
    SELECT M.CODE_MATIERE,M.LIBELLE,F.CODE_FOURNISSEUR
    FROM MATIERES M  JOIN F ON N.MATIERE=F.MATIERE
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    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 : 60
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut


    si tu es certain qu'il n'y a qu'un fournisseur principal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT M.CODE_MATIERE,M.LIBELLE,F.CODE_FOURNISSEUR
     FROM MATIERES M 
     LEFT JOIN FOURNIPAR F ON F.CODE_MATIERE=M.CODE_MATIERE AND F.PRINCIPAL='O'
    s'il peut y en avoir plusieurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT M.CODE_MATIERE,M.LIBELLE,MAX(F.CODE_FOURNISSEUR)
     FROM MATIERES M 
     LEFT JOIN FOURNIPAR F ON F.CODE_MATIERE=M.CODE_MATIERE AND F.PRINCIPAL='O'
     GROUP BY 1,2
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT M.CODE_MATIERE,M.LIBELLE,MIN(F.CODE_FOURNISSEUR)
     FROM MATIERES M 
     LEFT JOIN FOURNIPAR F ON F.CODE_MATIERE=M.CODE_MATIERE AND F.PRINCIPAL='O'
     GROUP BY 1,2
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 050
    Points : 40 982
    Points
    40 982
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par makowski Voir le message
    si tu es certain qu'il n'y a qu'un fournisseur principal
    Oui mais non justement , (voir jeu d'essai matiere 3) ,
    donc impossible de tester sur la colonne PRINCIPAL , cela aurait été trop simple
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    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 : 60
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    ce que je t'ai envoyé fonctionne

    ceci dit, ton modèle est mal fait s'il permet plusieurs "principaux"

    s'il peut y en avoir plusieurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT M.CODE_MATIERE,M.LIBELLE,MAX(F.CODE_FOURNISSEUR)
     FROM MATIERES M 
     LEFT JOIN FOURNIPAR F ON F.CODE_MATIERE=M.CODE_MATIERE AND F.PRINCIPAL='O'
     GROUP BY 1,2
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT M.CODE_MATIERE,M.LIBELLE,MIN(F.CODE_FOURNISSEUR)
     FROM MATIERES M 
     LEFT JOIN FOURNIPAR F ON F.CODE_MATIERE=M.CODE_MATIERE AND F.PRINCIPAL='O'
     GROUP BY 1,2
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 050
    Points : 40 982
    Points
    40 982
    Billets dans le blog
    62
    Par défaut
    Ce que tu m'as indiqué fonctionne parfaitement

    Mais , ce que je voulais dire c'est qu'il se peut qu'une matière n'ai aucun fournisseur principal
    (Soit parce que celui-ci a été supprimé et non remplacé
    Soit parce que jamais indiqué cela dépendant par exemple de l'appel d'offre)

    donc on peut se trouver dans les situations suivantes
    il y a un fournisseur principal
    il y a un fournisseur 'principal' et des 'occasionnels'
    il n'y a pas de fournisseur principal , que des occasionnels
    il n'y a aucun fournisseur
    le cas : il y a deux fournisseurs principaux n'est "encore" jamais arrivé (il y a une contrainte)

    [Note] le schéma est simplifié a l'extrême mais c'est a peu près ça
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  7. #7
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut Sergio

    ET avec des unions, qu'est-ce que ça donne ?
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    -- Founisseurs principaux
    SELECT
      M.CODE_MATIERE, M.LIBELLE, F.CODE_FOURNISSEUR, F.PRINCIPAL
    FROM
      MATIERES M
      INNER JOIN FOURNIPAR F
      ON M.CODE_MATIERE = F.CODE_MATIERE
    WHERE
      F.PRINCIPAL = 'O'
     
    -- Fournisseurs secondaires
    UNION
    SELECT
      M.CODE_MATIERE, M.LIBELLE, F.CODE_FOURNISSEUR, F.PRINCIPAL
    FROM
      MATIERES M
      INNER JOIN FOURNIPAR F
      ON M.CODE_MATIERE = F.CODE_MATIERE
    WHERE
      F.PRINCIPAL = 'N' AND
      NOT EXISTS(
        SELECT
          F2.CODE_MATIERE
        FROM
          FOURNIPAR F2
        WHERE
          F2.CODE_MATIERE = F.CODE_MATIERE AND
          F2.PRINCIPAL = 'O')
     
    -- Absence de fournisseur
    UNION
    SELECT
      M.CODE_MATIERE, M.LIBELLE, F.CODE_FOURNISSEUR, F.PRINCIPAL
    FROM
      MATIERES M
      LEFT OUTER JOIN FOURNIPAR F
      ON M.CODE_MATIERE = F.CODE_MATIERE
    WHERE
      F.CODE_FOURNISSEUR IS NULL;
    @+ Claudius

  8. #8
    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 : 60
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    donc on peut se trouver dans les situations suivantes
    il y a un fournisseur principal
    il y a un fournisseur 'principal' et des 'occasionnels'
    il n'y a pas de fournisseur principal , que des occasionnels
    il n'y a aucun fournisseur
    le cas : il y a deux fournisseurs principaux n'est "encore" jamais arrivé (il y a une contrainte)
    et bien mes requêtes répondent parfaitement à toutes ces situations et renvoi ce que tu disais vouloir obtenir
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  9. #9
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 050
    Points : 40 982
    Points
    40 982
    Billets dans le blog
    62
    Par défaut
    @Claudius Avé
    , oui ça ça pourrait marché avec une petite modification sur l'union des fournisseur secondaires pour n'avoir que le premier (le fameux Group by de makowski mais avc les F.PRINCIPAL='N')

    @makowski non je ne crois pas , (je refais un essai) mais dans les proposition que tu me fais seul les fournisseurs principaux apparaissent
    Citation Envoyé par a cause de
    AND F.PRINCIPAL='O'
    [Edit] je joins une partie des résultats pour t'en faire la preuve

    avec cette CTE cela fonctionne (enfin je n'ai pas encore vérifié toutes les matières du fichier REEL , il faut dire qu'il y en a +de 5000 et encore je ne parle pas des coloris <- quand j'ai dit que j'avais simplifié )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WITH F AS (SELECT R.MATIERE,(SELECT FIRST 1 M.CODE_FOURNISSEUR FROM FOURNIPAR M WHERE M.MATIERE=R.MATIERE ORDER BY M.MATIERE,M.PRINCIPAL DESC) AS FOURNISSEUR
    FROM MATFRN R)
    c'est juste que je trouve le SELECT dans un SELECT très inélégant
    et que certains SGBDR on une fonction pour extraire le 1°tuple , c'est pas pour cela que je changerai d'avis sur Firebird

    Reste a découvrir le plus performant

    [edit] y a pas photo , sur un jeu d'essai plus conséquent :
    avec l'union 0.249s (prepare inclus) 44064 fetches
    avec mes premiers essais (le select dans un select) 0.827s avec 684211 fetches

    Merci a vous 2 , un mix des diverses propositions donne (enfin) un résultat très satisfaisant

    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
    24
    25
    26
    27
    28
    29
     
    WITH F AS (-- Founisseurs principaux
    SELECT
      CODE_MATIERE,CODE_FOURNISSEUR
    FROM
      FOURNIPAR
    WHERE
      PRINCIPAL = 'O'
    -- Fournisseurs secondaires
    UNION
    SELECT
     F1.CODE_MATIERE,MIN(F1.CODE_FOURNISSEUR)
    FROM
      FOURNIPAR F1
    WHERE
      PRINCIPAL = 'N' AND
      NOT EXISTS(
        SELECT
          F2.CODE_MATIERE
        FROM
          FOURNIPAR F2
        WHERE
          F2.CODE_MATIERE = F1.CODE_MATIERE AND
          F2.PRINCIPAL = 'O')
    GROUP BY 1
    )
     
    SELECT DISTINCT M.CODE_MATIERE,F.CODE_FOURNISSEUR
    FROM MATIERES M LEFT JOIN F ON M.CODE_MATIERE=F.CODE_MATIERE
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  10. #10
    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 : 60
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    @makowski non je ne crois pas , (je refais un essai) mais dans les proposition que tu me fais seul les fournisseurs principaux apparaissent
    NON, clairement NON

    n'oublie pas que j'ai mis un LEFT JOIN
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  11. #11
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 050
    Points : 40 982
    Points
    40 982
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par makowski Voir le message
    NON, clairement NON
    n'oublie pas que j'ai mis un LEFT JOIN
    on est bien d'accord , et je n'obtiens que des couples matières,libelle/fournisseurs principal ou matières,libelle/null
    dans ce cas
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  12. #12
    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 : 60
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    oui,

    mais tu peux aussi essayer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT M.CODE_MATIERE,M.LIBELLE,
    COALESCE(MIN(F.CODE_FOURNISSEUR),
    (SELECT CODE_FOURNISSEUR FROM FOURNIPAR WHERE CODE_MATIERE=M.CODE_MATIERE AND PRINCIPAL='N'))
     FROM MATIERES M 
     LEFT JOIN FOURNIPAR F ON F.CODE_MATIERE=M.CODE_MATIERE AND F.PRINCIPAL='O'
     GROUP BY 1,2
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/04/2008, 14h49
  2. [VBA-E] Récuperer la premiere lettre d'une cellules
    Par cyraile dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 21/03/2007, 12h37
  3. recuperer le premier tuple
    Par agougeon dans le forum Sybase
    Réponses: 3
    Dernier message: 25/07/2006, 13h05
  4. [Tableaux] récuperer n premiers mots d'une chaine
    Par gibigue dans le forum Langage
    Réponses: 2
    Dernier message: 05/06/2006, 02h17
  5. [C#] Récuperer la premiere ligne d'un SqlDataReader
    Par Oberown dans le forum Windows Forms
    Réponses: 3
    Dernier message: 10/01/2005, 18h26

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