Précédent   Forum du club des développeurs et IT Pro > Bases de données > Autres SGBD > InterBase
InterBase Forum d'entraide sur le SGBD InterBase de Codegear. Avant de poster -> F.A.Q Interbase, Tutoriels
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 12/01/2012, 17h23   #1
billbocquet
Invité de passage
 
Homme
Inscription : janvier 2006
Messages : 20
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 60
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Secteur : Industrie

Informations forums :
Inscription : janvier 2006
Messages : 20
Points : 2
Points : 2
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.
billbocquet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2012, 09h04   #2
SergioMaster
Modérateur
 
Avatar de SergioMaster
 
Homme Serge Girard
Développeur informatique
Inscription : janvier 2007
Messages : 4 205
Détails du profil
Informations personnelles :
Nom : Homme Serge Girard
Âge : 56
Localisation : France

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

Informations forums :
Inscription : janvier 2007
Messages : 4 205
Points : 7 260
Points : 7 260
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
SergioMaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/01/2012, 12h29   #3
billbocquet
Invité de passage
 
Homme
Inscription : janvier 2006
Messages : 20
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 60
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Secteur : Industrie

Informations forums :
Inscription : janvier 2006
Messages : 20
Points : 2
Points : 2
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 ?
billbocquet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2012, 15h31   #4
billbocquet
Invité de passage
 
Homme
Inscription : janvier 2006
Messages : 20
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 60
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Secteur : Industrie

Informations forums :
Inscription : janvier 2006
Messages : 20
Points : 2
Points : 2
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;
billbocquet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 07h45   #5
SergioMaster
Modérateur
 
Avatar de SergioMaster
 
Homme Serge Girard
Développeur informatique
Inscription : janvier 2007
Messages : 4 205
Détails du profil
Informations personnelles :
Nom : Homme Serge Girard
Âge : 56
Localisation : France

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

Informations forums :
Inscription : janvier 2007
Messages : 4 205
Points : 7 260
Points : 7 260
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

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

Citation:
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
SergioMaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 10h21   #6
billbocquet
Invité de passage
 
Homme
Inscription : janvier 2006
Messages : 20
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 60
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Secteur : Industrie

Informations forums :
Inscription : janvier 2006
Messages : 20
Points : 2
Points : 2
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
Citation:
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.
billbocquet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2012, 10h42   #7
SergioMaster
Modérateur
 
Avatar de SergioMaster
 
Homme Serge Girard
Développeur informatique
Inscription : janvier 2007
Messages : 4 205
Détails du profil
Informations personnelles :
Nom : Homme Serge Girard
Âge : 56
Localisation : France

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

Informations forums :
Inscription : janvier 2007
Messages : 4 205
Points : 7 260
Points : 7 260
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
Citation:
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
Citation:
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
SergioMaster est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 01h25.


 
 
 
 
Partenaires

Hébergement Web