Fusionner 2 requêtes SQL

Messages postés
97
Date d'inscription
vendredi 19 octobre 2007
Statut
Membre
Dernière intervention
18 décembre 2013
- - Dernière réponse : 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.
Afficher la suite 

7 réponses

Messages postés
308
Date d'inscription
jeudi 29 septembre 2005
Statut
Membre
Dernière intervention
17 septembre 2013
1
0
Merci
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.
Commenter la réponse de beckerich
Messages postés
308
Date d'inscription
jeudi 29 septembre 2005
Statut
Membre
Dernière intervention
17 septembre 2013
1
0
Merci
re-salut,

cela doit être possible sur firebird :

voir ici.

Luc.
Commenter la réponse de beckerich
Messages postés
97
Date d'inscription
vendredi 19 octobre 2007
Statut
Membre
Dernière intervention
18 décembre 2013
5
0
Merci
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.
Commenter la réponse de grandyaka54
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
24
0
Merci
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.
Commenter la réponse de cs_Delphiprog
Messages postés
308
Date d'inscription
jeudi 29 septembre 2005
Statut
Membre
Dernière intervention
17 septembre 2013
1
0
Merci
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.
Commenter la réponse de beckerich
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
24
0
Merci
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.
Commenter la réponse de cs_Delphiprog
Messages postés
97
Date d'inscription
vendredi 19 octobre 2007
Statut
Membre
Dernière intervention
18 décembre 2013
5
0
Merci
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.
Commenter la réponse de grandyaka54