Vous n'êtes pas identifié(e).

#1 17/02/2012 12:10:02

HadanMarv
Membre

Conception requête complexe

Bonjour,

J'ai une table commande et une table commande_historique.
Lors de la création de ma commande, j'insère un enregistrement dans ma table commande_historique.
Je fait de même à chaque fois que je change l'état de ma commande.
J'obtiens ainsi :

Table Commande
ID    |Etat      |User    |Prix
1      |Validé  |Admin  |50

Table Commande_historique
ID    |ID_COMMANDE    | User    |Etat          |Date
1      |1                        |Client   |Créé         |2012-01-01 19:50:25
2      |1                        |Admin   |Accepté    |2012-01-02 07:45:17
3      |1                        |Client   |Modifié      |2012-01-02 10:37:01
4      |1                        |Admin   |Accepté    |2012-01-02 14:28:13
5      |1                        |Admin   |Validé      |2012-01-03 08:01:52

Avec ces informations je voudrais pouvoir en une requête produire le résultat suivant :
ID_COMMANDE    |Etat        |Durée
1                        |Créé       |0jour 11 heures 54 minutes 52 secondes
1                        |Accepté   |0jour 02 heures 51 minutes 44 secondes
1                        |Modifié    |0jour 03 heures 51 minutes 12 secondes
1                        |Accepté   |0jour 17 heures 33 minutes 39 secondes

Les calculs correspondent au temps écoulés entre deux dates ici toujours moins de 1 jour, mais çà peut parfois être plus.
Si quelqu'un à une solution j'suis preneur.
J'avoue que je me fais des noeuds au cerveau en essayant de résoudre ce cas.

D'avance merci de vos réponses.
HadanMarv

Hors ligne

#2 17/02/2012 12:27:00

Marc Cousin
Membre

Re : Conception requête complexe

Le plus simple pour résoudre ça, c'est une Window Function

SELECT id_commande,
       username,
       etat,
       date_evt,lead(date_evt) over (partition by id_commande order by date_evt) - date_evt
from commande_historique ;
id_commande | username |  etat   |        date_evt        | ?column?
-------------+----------+---------+------------------------+----------
           1 | Client   | Créé    | 2012-01-01 19:50:25+01 | 11:54:52
           1 | Admin    | Accepté | 2012-01-02 07:45:17+01 | 02:51:44
           1 | Client   | Modifié | 2012-01-02 10:37:01+01 | 03:51:12
           1 | Admin    | Accepté | 2012-01-02 14:28:13+01 | 17:33:39
           1 | Admin    | Validé  | 2012-01-03 08:01:52+01 |

Disponible à partir de PostgreSQL 8.4: http://docs.postgresql.fr/9.1/tutorial-window.html


Marc.

Hors ligne

#3 17/02/2012 12:36:18

rjuju
Administrateur

Re : Conception requête complexe

Bonjour.
Il suffit de joindre la table d'historique sur elle-même :

select deb."ID_COMMANDE",deb."Etat",fin."Date"-deb."Date" as "Durée"
from "Commande_historique" deb
join "Commande_historique" fin on deb."ID_COMMANDE" = fin."ID_COMMANDE"
	and deb."ID"+1=fin."ID"

Edit: Effectivement encore plus simple en window function.

Dernière modification par rjuju (17/02/2012 12:39:37)

Hors ligne

#4 17/02/2012 12:45:36

HadanMarv
Membre

Re : Conception requête complexe

Et bien quoi dire mise à part merci beaucoup.
J'avoue honnêtement ne rien comprendre à la requête fourni, mais cela fonctionne parfaitement.
Pourriez-vous m'éclairer sur son fonctionnement (partition, lead, over) ?
D'avance merci

HadanMarv

Hors ligne

#5 17/02/2012 12:58:03

Marc Cousin
Membre

Re : Conception requête complexe

Le mieux, c'est pour commencer que vous lisiez la page de doc que j'ai mise en lien : http://docs.postgresql.fr/9.1/tutorial-window.html . Elle explique assez bien le principe (même si ce n'est pas évident à appréhender initialement). Si je vous l'explique, je ne ferai que redire ce qui est écrit sur cette page. Si vous avez encore besoin d'éclaircissements après, n'hésitez pas à poser des questions.


Marc.

Hors ligne

Pied de page des forums