Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 7 sur 7
  1. #1
    Invité de passage
    Homme Profil pro Christian BOCQUET
    Retraité
    Inscrit en
    janvier 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Nom : Homme Christian BOCQUET
    Âge : 61
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2006
    Messages : 20
    Points : 3
    Points
    3

    Par défaut Sous-requête retournant une table

    Bonjour,
    Je voudrais exécuter une requête de ce type
    Code :
    1
    2
    3
    SELECT champ1, 
    FROM ( SELECT champ1, champ2 FROM table1 ORDER BY champ2) T2
    GROUP BY champ1
    Le debugger donne une erreur "token unknow" sur le 2ième select.
    Est-ce qu'interbase n'accepte pas les sous-requêtes retournant une table?
    Si oui, comment peut-on s'en sortir facilement?

    J'utilise DelphiXE entreprise et INTERBASE fourni avec (interbase 2009).

    Merci d'avance pour votre aide.

  2. #2
    Rédacteur/Modérateur
    Avatar de SergioMaster
    Homme Profil pro Serge Girard
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    5 306
    Détails du profil
    Informations personnelles :
    Nom : Homme Serge Girard
    Âge : 58
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 5 306
    Points : 9 685
    Points
    9 685

    Par défaut

    Déjà , dans ce SQL il y a une virgule en trop

    sous Firebird j'aurais fait une CTE (je suis fan , de plus c'est plus facile a lire)

    interbase accepte t'il cette syntaxe

    Code :
    1
    2
    WITH T2 AS (SELECT champ1, champ2 FROM table1)
    SELECT champ1,Sum(champ2) FROM t2 GROUP BY champ1
    ce qui permet des choses comme

    Code :
    1
    2
    3
    4
    5
    WITH T1 AS (SELECT champ1, champ2 FROM table1),
                         T2 AS (SELECT Champ1,Sum(Champ3) AS St3 FROM table2 
                                    GROUP BY champ1)
    SELECT champ1,Sum(champ2),max(st3)  FROM t1 JOIN t2 ON t1.champ1=t2.champ1
    GROUP BY champ1
    mais tout cela est trop vague
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein
    J'entends et j'oublie. Je vois et je me souviens. Je fais et je comprends . Confucius
    Si votre seul outil est un marteau, vous aurez tendance a ne voir que des clous

  3. #3
    Invité de passage
    Homme Profil pro Christian BOCQUET
    Retraité
    Inscrit en
    janvier 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Nom : Homme Christian BOCQUET
    Âge : 61
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2006
    Messages : 20
    Points : 3
    Points
    3

    Par défaut

    La syntaxe With n'est pas acceptée par interbase.
    Est-ce qu'une solution comme indiquée ci-dessous serait envisageable?
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CREATE TABLE T2 AS 
    SELECT champ1, champ2 FROM table1 WHERE champ2='Une valeur' 
    //EXEC SQL
     
    SELECT champ1 FROM T2 
    GROUP BY champ1
     
    //Utilisation du résultat du SELECT ->Rempli les Items d''une ComboBox à l''aide du champ1
     
    CLOSE T2
    //EXEC SQL
     
    DROP T2
    //EXEC SQL
    Si cette solution fonctionne, créer une table pour un tri intermédiaire me parait très lourd.
    N'y a t-il vraiment pas de solution simple pour ce problème, avec INTERBASE ?

  4. #4
    Invité de passage
    Homme Profil pro Christian BOCQUET
    Retraité
    Inscrit en
    janvier 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Nom : Homme Christian BOCQUET
    Âge : 61
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2006
    Messages : 20
    Points : 3
    Points
    3

    Par défaut

    Bon,.. comme à priori, INTERBASE ne semble pas très bon sur ce coup là, je me suis rabattu sur la programmation pascal habituelle pour résoudre mon problème.
    Ce que j'avais besoin, c'est une liste d'items d'un champ, en assurant qu'il n'y ait aucune redondance.
    J'ai codé ça
    Code :
    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
    vSQL:='SELECT champ1, champ2 from table1 WHERE Champ2 = "UneCertaineValeur"';
    iniComboBoxNonRedondance(Combo_NomCommercial,IBQuery_JeuxPourNomCommercial,vSQL,'champ1');
    {------------------------------------------------------------------------------}
    procedure TfrmEcranPourOperateur.iniComboBoxNonRedondance(Cbx: TComboBox; Dset :TDataset; const vSQL, Champ1:string);
    {Initialise une ComboBox en interdisant toute redondance.                      }
    var
     I : integer;
     ChampItems : TStringList;
    begin
     ChampItems:=TStringList.CREATE;
     Cbx.Clear;
     IF IBDatabaseSuiviAff_Mach.Connected then begin
         IF Dset IS TIBQuery then
             IBQuery_SelectCloseOpen(Dset,vSQL);
         ChampItems.Clear;
         ChampItems.Sorted:=true;
         ChampItems.Duplicates:=dupIgnore;
         while NOT Dset.Eof do begin
             IF Dset.FieldByName(Champ1).AsString<>'' then begin
                 ChampItems.ADD(Dset.FieldByName(Champ1).AsString);
                 end;
             Dset.Next;
         end;
         Dset.First;
         FOR I := 0 TO ChampItems.Count-1 do
             Cbx.Items.ADD(ChampItems.Strings[I]);
         end;
     Cbx.Sorted:=true;
     Cbx.ItemIndex:=0;
     Cbx.Text:=Cbx.Items[Cbx.ItemIndex];
     ChampItems.Destroy;
    end;
    et ça fonctionne!
    En fait, toute l'astuce est dans le
    Code :
    ChampItems.Duplicates:=dupIgnore;

  5. #5
    Rédacteur/Modérateur
    Avatar de SergioMaster
    Homme Profil pro Serge Girard
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    5 306
    Détails du profil
    Informations personnelles :
    Nom : Homme Serge Girard
    Âge : 58
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 5 306
    Points : 9 685
    Points
    9 685

    Par défaut

    Et avec des Vues (VIEW) ?

    Sur mes vieux souvenirs , une vue ne stocke (duplique) pas les données mais seulement le SQL
    ensuite il suffit d'utiliser la vue comme une table

    euh , pas besoin du duplicates:=dupIgnore un DISTINCT fait l'affaire

    vSQL:='SELECT DISTINCT champ1, champ2 from table1 WHERE Champ2 = "UneCertaineValeur"';
    ou un GROUP BY

    vSQL:='SELECT champ1, Max(champ2) from table1 WHERE Champ2 = "UneCertaineValeur"';
    GROUP BY 1
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein
    J'entends et j'oublie. Je vois et je me souviens. Je fais et je comprends . Confucius
    Si votre seul outil est un marteau, vous aurez tendance a ne voir que des clous

  6. #6
    Invité de passage
    Homme Profil pro Christian BOCQUET
    Retraité
    Inscrit en
    janvier 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Nom : Homme Christian BOCQUET
    Âge : 61
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2006
    Messages : 20
    Points : 3
    Points
    3

    Par défaut

    J'ai essayé avec
    Code :
    1
    2
    vSQL:='SELECT champ1, Max(champ2) from table1 WHERE Champ2 = "UneCertaineValeur"';
    GROUP BY champ1
    et ça fonctionne bien. J'obtiens moins d'Items qu'avec ma programmation, mais j'ai vérifié, il y a des valeurs de Champ2 qui sont quelque fois égales à null, donc ça doit être normal.
    L'astuce ici est donc d'inclure un champ dans un GROUP BY en utilisant un Max( ) afin de pouvoir utiliser cette variable dans le WHERE. Je ne savais pas que l'on pouvait faire cela!
    Cette solution est intéressante car très simple. Le tout est de savoir jongler avec les requêtes SQL...
    Au sujet de pouvoir résoudre le problème (ce n'est plus vraiment d'actualité du fait que la méthode donnée ci-dessus est pleinement satisfaisante, mais j'aime bien savoir...) avec une Table ou View intermédiaire:
    - View->J'ai envisagé la chose, mais comme j'étais obligé de résoudre le Pb en 2 temps
    Code :
    1
    2
    3
    4
    5
    6
    CREATE VIEW T2 AS 
    SELECT champ1, champ2 FROM table1 WHERE champ2='Une valeur' 
    //EXEC SQL
     
    SELECT champ1 FROM T2 
    GROUP BY champ1
    J'ai lu qu'il n'était pas possible de faire un SELECT sur un View. Une fois créé, on peut lire ce qu'il y a dedans, mais on ne peut plus travailler sur ses données... donc j'ai obté pour la table.
    - Dans mes essais avec la VIEW et la TABLE, à la création, pas de problème, mais au moment du DROP, j'ai obtenu une erreur du type
    la Table/View est utilisée, il n'est pas possible de l'enlever
    Je n'ai pas su aller plus loin.
    - Un dernier point au sujet du travail sur une table intermédiaire. Si un premier utilisateur par l'application créé la table
    Code :
    1
    2
    CREATE TABLE T2 AS 
    SELECT champ1, champ2 FROM table1 WHERE champ2='Une valeur'
    ->COMMIT. Un autre presque au même moment fait la même chose->Il y a une 2ième création de table! L'appli du 1ier fait
    Code :
    1
    2
    SELECT champ1 FROM T2 
    GROUP BY champ1
    , puis COMMIT, Etc... c'est la sac de noeuds complet!
    Qu'est-ce qui se passe en réalité. Mon hypothèse de travail est peut être complètement farfelue. Merci de m'éclairer à ce sujet.

  7. #7
    Rédacteur/Modérateur
    Avatar de SergioMaster
    Homme Profil pro Serge Girard
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    5 306
    Détails du profil
    Informations personnelles :
    Nom : Homme Serge Girard
    Âge : 58
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 5 306
    Points : 9 685
    Points
    9 685

    Par défaut

    Citation Envoyé par billbocquet Voir le message
    J'ai essayé avec
    Code :
    1
    2
    vSQL:='SELECT champ1, Max(champ2) from table1 WHERE Champ2 = "UneCertaineValeur"';
    GROUP BY champ1
    et ça fonctionne bien. J'obtiens moins d'Items qu'avec ma programmation, mais j'ai vérifié, il y a des valeurs de Champ2 qui sont quelque fois égales à null, donc ça doit être normal.
    ça c'est qu'une question de Where à manier , le distinct doit fonctionner aussi
    J'ai lu qu'il n'était pas possible de faire un SELECT sur un View. Une fois créé, on peut lire ce qu'il y a dedans, mais on ne peut plus travailler sur ses données...
    Première nouvelle
    Mon hypothèse de travail est peut être complètement farfelue. Merci de m'éclairer à ce sujet.
    OUI , c'est farfelu j'y mets une ampoule 100W

    le problème c'est que tu semble absolument vouloir passer par des tables intermédiaires a créer et détruire (des GLOBAL TEMPORARY TABLE dans le jargon, ça existe , la preuve) mais tu demandes de l'aide en mettant demandant des ordres tellement généraux qu'il est très difficile de répondre :

    un
    Code :
    SELECT champ1,champ2 FROM table1 WHERE champ2="une valeur"
    franchement c'est pas terrible , dans ton cas on ne sait pas
    - Quelle est la structure de la table, s'il y a des index , le type de champ et s'il est 'nullifiable' !
    - aucun jeu d'essai
    - aucun élément sur le résultat a trouver

    une demande très vague (on n'est pas dans ta tête) ne pourra que donner une réponse vague (le fameux 'GIGO')
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein
    J'entends et j'oublie. Je vois et je me souviens. Je fais et je comprends . Confucius
    Si votre seul outil est un marteau, vous aurez tendance a ne voir que des clous

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •