Fusionner 2 requêtes SQL

grandyaka54 Messages postés 97 Date d'inscription vendredi 19 octobre 2007 Statut Membre Dernière intervention 18 décembre 2013 - 9 juin 2011 à 11:28
grandyaka54 Messages postés 97 Date d'inscription vendredi 19 octobre 2007 Statut Membre Dernière intervention 18 décembre 2013 - 14 juin 2011 à 10:58
Bonjour à tous,

Avant de vous exposez le problème, je précise que j'utilise Delphi2009, FireBird 2.1 et les composants IBQuery, DataSource et DBGrid.

J'ai une table Virement avec les champs suivants :
- IDVir (Numéro d'incrémentation)
- DateECH (Date d'échéance du virement)
- NomClient (Nom du client destinataire du virement)
- Montant (Montant du virement)
- Etat (Virement Disponible (D) ou en Remise (R))
- ....

Actuellement, j'utilise un IBQuery pour enregsitrer la requête SQL ci-dessous et j'affiche le résultat dans un DBGrid via le DataSource.

SELECT IDVir , DateECH, Etat, Montant, Client
FROM VIREMENT
ORDER BY Etat, DateEch DESC, Montant

Ce qui donne par exemple :

|IDVir| DateEch | Etat| Montant | NomClient |
|-----|----------|-----|---------|-----------|
|229 | 11/03/11 | D | 55,00 | Toto |
|219 | 31/01/11 | D | 12,00 | Titi |
|249 | 12/04/11 | R | 100,00 | Titi |
|226 | 02/03/11 | R | 65,00 | Tutu |
|215 | 25/10/10 | R | 452,00 | Tata |

Or, on me demande de modifier l'ordre de tri au niveau du champ DateECH en fonction du champ Etat.
Je m'explique, lors du tri, je dois afficher pour :
- Les virements avec l'Etat = D, la date de la plus ancienne à la plus récente (ASC).
- Les virements avec l'Etat = R, la date la plus récente à la plus ancienne (DESC).
et afficher le résultat dans le même DBGrid.

A part créer deux requêtes et lier ces 2 requêtes vers un DBGrid chacun, je ne vois pas comment fusionner ces deux requêtes dans le même DBGrid pour avoir le résultat suivant :

|IDVir| DateEch | Etat| Montant | NomClient |
|-----|----------|-----|---------|-----------|
|219 | 31/01/11 | D | 12,00 | Titi | \ Ces lignes sont inversées.
|229 | 11/03/11 | D | 55,00 | Toto | /
|249 | 12/04/11 | R | 100,00 | Titi |
|226 | 02/03/11 | R | 65,00 | Tutu |
|215 | 25/10/10 | R | 452,00 | Tata |

Merci d'avance pour l'aide et si vous avez d'autres question n'hésité pas.

Cordialement.

7 réponses

beckerich Messages postés 302 Date d'inscription jeudi 29 septembre 2005 Statut Membre Dernière intervention 17 septembre 2013 2
10 juin 2011 à 14:16
Bonjour,

sur informix, j'y arrive comme cela :

CREATE TEMP TABLE a
  (
    txt  CHAR(4)
   ,val  SMALLINT
  ) ;
 
INSERT INTO a VALUES ("toto",1) ;
INSERT INTO a VALUES ("titi",2) ;
INSERT INTO a VALUES ("titi",9) ;
INSERT INTO a VALUES ("toto",4) ;
INSERT INTO a VALUES ("titi",6) ;
INSERT INTO a VALUES ("toto",3) ;
 
SELECT txt
     , val
     , CASE WHEN txt = "toto" THEN val
            WHEN txt = "titi" THEN -1*val
       END tri
  FROM a
 ORDER BY 1,3 ;
 
txt     val              tri
----    ---              ---
titi      9               -9
titi      6               -6
titi      2               -2
toto      1                1
toto      3                3
toto      4                4


Faut voir avec ton SGDB, sinon passer par une table temporaire. Et puis adresser cette question sur le forum SQL serait mieux.
ICI

Luc.
0
beckerich Messages postés 302 Date d'inscription jeudi 29 septembre 2005 Statut Membre Dernière intervention 17 septembre 2013 2
10 juin 2011 à 14:24
re-salut,

cela doit être possible sur firebird :

voir ici.

Luc.
0
grandyaka54 Messages postés 97 Date d'inscription vendredi 19 octobre 2007 Statut Membre Dernière intervention 18 décembre 2013 5
10 juin 2011 à 16:30
Bonjour beckerich,

D'abord un grand merci d'avoir pris le temps de me répondre.
Je ne connaissait absolument pas cette méthode.

J'ai repris ton exemple et ça a marché pour un tri sur les montants.
Maintenant, il faut que je cherche comment faire cela sur les dates.

Encore merci de ton aide ^^

Grandyaka.
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
13 juin 2011 à 10:12
En utilisant la jointure d'union(cf sqlpro), tu peux joindre plusieurs requêtes les unes à la suite des autres comma ceci, par exemple :
SELECT idvir,
       dateech,
       etat,
       montant,
       client
FROM   virement
WHERE  etat = 'D'
ORDER  BY etat,
          dateech ASC,
          montant

UNION JOIN
SELECT idvir,
       dateech,
       etat,
       montant,
       client
FROM   virement
WHERE  etat = 'R'
ORDER  BY etat,
          dateech DESC,
          montant 



Les enregistrements apparaissent dans l'ordre des SELECT saisis.

May Delphi be with you

Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
beckerich Messages postés 302 Date d'inscription jeudi 29 septembre 2005 Statut Membre Dernière intervention 17 septembre 2013 2
13 juin 2011 à 13:34
Bonjour DelphiProg,

as-tu testé ton code ? Je pense que l'order by dans un select union ne peut se faire que sur le dernier select.


firebird 2.4
Ce code rapporte une erreur :
error code: -104

SELECT distinct coddoc from tdcou 
where aneexe = 2010 
order by 1

union 

SELECT count(serdoc) from tdcou 
where aneexe = 2010 


celui-ci fonctionne :
SELECT distinct coddoc from tdcou 
where aneexe = 2010 

union 

SELECT count(serdoc) from tdcou 
where aneexe = 2010 

order by 1


Luc.
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
13 juin 2011 à 16:02
Bonjour Luc,

J'ai rédigé ce code de mémoire. Ceci explique cela.
Et tu as parfaitement raison de me faire remarquer que ce code ne fonctionne pas. Mais l'idée est là.
Pour pouvoir utiliser les clauses WHERE dans chacune des sous requêtes, il faut utiliser les parenthèses, comme ceci :
(
SELECT idvir,
       dateech,
       etat,
       montant,
       nomclient
FROM   virement
WHERE  etat = 'D'
ORDER  BY dateech ASC, montant
)

UNION DISTINCT

(
SELECT idvir,
       dateech,
       etat,
       montant,
       nomclient
FROM   virement
WHERE  etat = 'R'
ORDER  BY dateech DESC, montant
)


Hélas, le résultat n'est pas à la hauteur de ce que souhaite obtenir grandyaka54.
Sous MySQL, les deux ensembles de résultats sont bien mis à la suite les uns des autres mais le contenu de chacun reste ordonné de façon décroissante.
Voici le résultat obtenu :
1, '2011-03-11', 'D', 55.00, 'toto'
2, '2011-01-31', 'D', 12.00, 'titi'
3, '2011-04-12', 'R', 100.00, 'titi'
4, '2011-03-02', 'R', 65.00, 'tutu'
5, '2010-10-25', 'R', 452.00, 'tata'

Pourtant, quand on lit la doc, cela semble possible :
"To additionally maintain sort order within individual SELECT results, add a secondary column to the ORDER BY clause:

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col, col1a;

"
Mais ça ne produit pas l'effet recherché ou alors j'interprète mal (mon code ci-dessus n'intègre pas les recommandations de MySQL).
Je persévère donc...

May Delphi be with you

Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0
grandyaka54 Messages postés 97 Date d'inscription vendredi 19 octobre 2007 Statut Membre Dernière intervention 18 décembre 2013 5
14 juin 2011 à 10:58
Bonjour à tous !

Merci pour ton aide Delphiprog. J'avais effectivement utilisé la jointure d'union pour additionner deux requêtes.
Mais j'avais eu le même message d'erreur que Beckerich à savoir, impossible de mettre un Order By dans chaque commande.

Même en mettant les parenthèses entre chaque Select, Firebird me rapporte le code d'erreur :
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 1, char 1.
(.

Je continue à chercher de mon côté.

Encore merci de votre aide ^^.

Grandyaka.
0
Rejoignez-nous