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

 Delphi Discussion :

question query probleme


Sujet :

Delphi

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Autriche

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2018
    Messages : 23
    Points : 11
    Points
    11
    Par défaut question query probleme
    Salut tout le monde ! j'ai un petit problème ;
    j'ai 3 tables ; table1,table2,table3
    table1(codef,coder) //pour chaque codef on peut avoir plusieurs coder
    table2(coder,libelle,teinte)
    table3 (codef,designation,indice)
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT DISTINCT codef,coder,designation
    FROM table1
    inner JOIN table2
    on (table1.coder=table2.coder)
    inner join table3
    on (table3.codef=table1.codef)
    comment faire pour afficher un codef qui a plusieurs coder sur une seule ligne ?

    codef coder1 coder2 coder3
    1 15 18 31
    pour ma part ça s'affiche

    1 15
    1 18
    1 31
    merci pour tout!

  2. #2
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 611
    Points
    3 611
    Par défaut
    Vu que SQL fonctionne par enregistrement, ce ne serait possible qu'en bidouillant les requêtes et en jouant soit avec des procédures stockées, soit par code une fois la requête exécutée.
    A ma connaissance, il n'y a donc pas de solution pour ta question avec un simple SELECT.

  3. #3
    Membre éprouvé
    Homme Profil pro
    Chef de projets retraité
    Inscrit en
    Juillet 2011
    Messages
    420
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Chef de projets retraité
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 420
    Points : 1 102
    Points
    1 102
    Par défaut
    Bonjour,

    Tout dépend de ton moteur SQL (non précisé).

    Les résultats peuvent être obtenus
    + soit de la commande PIVOT selon ton moteur,
    + soit du la fonction GROUP_CONCAT selon ton moteur
    + sinon lorsque le nombre de "coder" est connu via des instructions Case (dans la plupart des moteurs).
    + ou peut être autre chose (mais je ne vois pas pour l'instant)

    Cordialement

  4. #4
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 689
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 689
    Points : 13 118
    Points
    13 118
    Par défaut
    Ce que tu souhaites faire s'appelle un pivot.

    A partir de ta première requête tu génères une liste de colonnes qui sera utilisée dans une deuxième requête.
    Pour Firedac/MySQL, ça se fait en une commande :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SET @Cols := NULL;
     
    -- Génère les colonnes CoderX ------------------------------------------------------------------------------
    SELECT GROUP_CONCAT(Coder) INTO @Cols
    FROM (SELECT ...) tmp;
     
    -- Requête finale ------------------------------------------------------------------------------------------
    SET @SQL = CONCAT_WS(' ', 'SELECT Codef,', @Cols, 'FROM ...');
     
    PREPARE Script FROM @SQL;
    EXECUTE Script;
    DEALLOCATE PREPARE Script;

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Autriche

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2018
    Messages : 23
    Points : 11
    Points
    11
    Par défaut
    re-salut ; j'utilise delphi 7 /absolute database ,votre solution est ambigue pour moi !

  6. #6
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut


    je ne connais pas cette base de donnée.
    Accepte elle les tables temporaire, si oui tu
    peut réaliser a l'aide du sql et de Delphi

    la première phase récupérer les nom des champs que tu veut sommer
    par exemple

    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
     
     
       stQuery := ' SELECT DISTINCT codef,coder,designation ' 
      +' FROM table1 '
      +'  inner JOIN table2 '
      +'  on (table1.coder=table2.coder) '
      +'   inner join table3 '
      +'  on (table3.codef=table1.codef) '
       CloseDataset(QrDatas);
       QrDatas.Sql.clear;
       QrDatas.Sql.add(stQuery);
      OpenDataset(QrDatas);
     
      st := 'Create table #TmpDatas( '
      +' codef Integer '
      // ... si tu as d'autre champs clé a mettre c'est ici 
     
      DefChps := '';
      PlusChp := '';
      SumChp  := '';
      Chps    := '';
      QrDatas.First;
      While not(QrDatas.Eof) Do
      begin
        DefChps := DefChps +Format(' ,%s numeric(13,3) default 0',[strTrimA(QrDatas.fields[2].AsString)]);
        Chps    := Chps     +Format(' ,%s ',[strTrimA(QrDatas.fields[2].AsString)]);
        SumChp  := SumChp   +Format(' ,sum(%s)',[strTrimA(QrDatas.fields[2].AsString)]);
        PlusChp := PlusChp +Format(' + %s ',[strTrimA(QrDatas.fields[2].AsString)]);
        QrDatas.next;
      end;
      st := st+DefChps+')' ;
      ExecSQL(st);
    une fois réaliser la construction de la table temporaire on va la remplir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     QrDatas.first;
      While not(QrDatas.Eof) Do // on Construit le tableau 
      begin
        st := ' Insert into #TmpDatas( codef,%0:s ) '
        +' SELECT codef,sum(coder) '
        +' from table1 '
        +' where designation = "%0:s" ) '
        ExecSQL(Format(st,[Trim(QrDatas.fields[2].AsString)]));
        QrDatas.next;
      end;

    une fois réalisé le fameux pivot
    reste plus qu'a sommer et regrouper par coeff

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
       st := ' Create Table #DatasFI (codef integer ';
      st := st+DefChps+')' ;
      ExecSQL(st);
     
      st := 'Insert into #DatasFI ( codef   ';
      st := st+Chps+' ) SELECT codef  ';
      st := st+SumChp+ ' from #TmpDatas GROUP by codef ';
      ExecSQL(st);
    voila en gros les étapes à faire pour transformer une table en ligne
    rien de compliqué mais bien connaitre son besoin d'origine et celui a obtenir
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Autriche

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2018
    Messages : 23
    Points : 11
    Points
    11
    Par défaut
    Re-salut ; c'est bien j'ai appris quelque chose 'PIVOT' mais ; toujours pas de progression dans la matière ; j'utilise Delphi 7 avec ABSOLUTE DATABASE comme SGBD i need more help please!

  8. #8
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    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 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Si j'en crois la documentation ABSOLUTE DATABASE n'a pas de fonction pivot, ni de group_concat ou list (firebird) donc côté SQL c'est "mort".
    Donc la seule solution, proposée par anapurna, est de créer une table temporaire, à partir de la table1 et faire le boulot par code.

    pour faire simple il faut créer un table temporaire de stucture table_temp(codef,coders)
    ou coders sera une chaine avec les codes coder séparés par une virgule
    pour obtenir selon l'exemple
    codef,coders
    1 15,18,31

    Mais, attention, '15,18,31' c'est une seule colonne pas 3 colonnes
    S'il faut vraiment que ce soit par colonnes, il faudra passer par une autre table temporaire à construire au runtime.
    Il faudra tout d'abord obtenir le nombre maximum de coder pour un codif, première requête
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MAX(N) FROM (select codef,count(1) N from table1 group by codef)
    puis, obligatoirement par code, construire la dite table temporaire en fonction du nombre obtenu pour enfin la remplir à partir d'une requête comme
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT CODEF,CODER FROM table1 ORDER BY CODEF
    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

  9. #9
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    on peut avoir la structure de tes tables

    les champs que tu veut regrouper et la cle de ta table en ligne


    [CODEF][CODER][DESIGNATION]
    [1] [X] [CODER1]
    [1] [X] [CODER2]
    [1] [X] [CODER1]
    [1] [X] [CODER3]
    [1] [X] [CODER2]
    et tu veux

    [CODEF][CODER1][CODER2][CODER3]
    [1] [X] [X] [X]
    c'est bien cela
    donc il faut construire ta table réceptrice dynamiquement
    et ensuite insérer les données dans les bonnes colonnes

    c'est ce que je t'ai expliquer dans mon premier poste
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  10. #10
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Autriche

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2018
    Messages : 23
    Points : 11
    Points
    11
    Par défaut
    est-ce comme ça?
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT MAX(N) FROM (select codef, count(1) N from table1 group by codef)
    CREATE TEMPORARY TABLEtmp AS SELECT CODEF,CODER FROM table1 ORDER BY CODEF
    ;

  11. #11
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    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 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Non, il faut créer la table temporaire dans le code Delphi
    puis, obligatoirement par code, construire la dite table temporaire en fonction du nombre obtenu pour enfin la remplir
    par exemple en construisant le SQL comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Var SQL : String;
     
    SQL:='CREATE TABLE  CODEF_CODER (CODEF INTEGER';
    for i:=1 to N  do // n obtenu de la première requête
     begin
       SQL:=SQL+', CODER'+InttoStr(N)+' INTEGER';
     end;
    SQL:=SQL+')';
    Query.SQL.Text:=SQL;
    Query.ExecSQL;
    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 à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Autriche

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2018
    Messages : 23
    Points : 11
    Points
    11
    Par défaut
    merci pour Tous et a SergioMaster vous êtes top !

  13. #13
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    Citation Envoyé par SergioMaster Voir le message
    Non, il faut créer la table temporaire dans le code Delphi

    par exemple en construisant le SQL comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Var SQL : String;
     
    SQL:='CREATE TABLE  CODEF_CODER (CODEF INTEGER';
    for i:=1 to N  do // n obtenu de la première requête
     begin
       SQL:=SQL+', CODER'+InttoStr(N)+' INTEGER';
     end;
    SQL:=SQL+')';
    Query.SQL.Text:=SQL;
    Query.ExecSQL;
    c'est prendre de gros risque imaginons que il n'y ai pas d’élément dans 2
    mais il y en ai dans 4 tu vas te trouver soit avec une colonne vide soit oublier la dernière colonne

    j'ai été confronté a ce genre de problème de tableaux dynamique
    il est préférable de faire une boucle sur la clé de rassemblement dans notre cas CoderX
    je suppose que coderX correspond a la désignation.

    mes deux cents
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  14. #14
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    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 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par anapurna Voir le message
    c'est prendre de gros risque imaginons que il n'y ai pas d’élément dans 2
    mais il y en ai dans 4 tu vas te trouver soit avec une colonne vide soit oublier la dernière colonne
    Non, puisque la requête SELECT MAX(N) FROM (select codef, count(1) N from table1 group by codef)permet d'avoir le maximum d'occurences pour un codef.

    Le remplissage n'est ensuite qu'un exercice de ce que je nomme une rupture de contrôle sur codref
    mais puisque c'est résolu, je pense que wisetechacer a compris cette partie.

    Cela dit je préfére nettement un SGBD qui permet les PIVOTS même les dernières versions de SQLite le propose
    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

  15. #15
    Membre éprouvé
    Homme Profil pro
    Chef de projets retraité
    Inscrit en
    Juillet 2011
    Messages
    420
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Chef de projets retraité
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 420
    Points : 1 102
    Points
    1 102
    Par défaut
    Bonjour,

    Citation Envoyé par SergioMaster Voir le message
    Cela dit je préfére nettement un SGBD qui permet les PIVOTS même les dernières versions de SQLite le propose
    C'est bizarre je n'en ai encore pas vu trace dans la doc SQLITE!

    Cordialement

  16. #16
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    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 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Par pivots, j'entendais les fonctions de fenêtrage https://www.sqlitetutorial.net/sqlite-window-functions/ https://sqlite.org/windowfunctions.html
    disponibles à partir de la version 3.25.

    En gros c'est donc inclus dans les connexion Firedac (en mode statique, par défaut) pour les versions 10.3.3 et plus.
    Je ne peux malheureusement que tester pour les versions avec les derniers updates et ce grâce à une simple reqête : select sqlite_version()10.2.3 (Tokyo) -> sqlite_version 3.9.2
    10.3.3 (Rio) -> sqlite_version 3.28.0
    10.4.1 (Sidney) -> sqlite_version 3.31.1
    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

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 23/10/2012, 10h05
  2. [AC-2003] Operation must use an updatable query Problem
    Par Bonero dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 08/02/2012, 16h41
  3. Question SVG: probleme avec RepeatCount
    Par chris109 dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 24/08/2010, 12h49
  4. questions et problemes sur le dispatch()
    Par Sylobiwan dans le forum JSF
    Réponses: 1
    Dernier message: 16/01/2008, 15h53
  5. as400 sql/QUERY probleme de dates
    Par philswiss dans le forum Requêtes
    Réponses: 1
    Dernier message: 19/07/2007, 06h16

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