PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

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

#1 20/06/2011 20:53:51

damalaan
Membre

Requete de regroupement

Bonjour,

J'ai des données qui peuvent ressembler à  ça :
date;esp;trn;ecartype
110402;2;2;12
110402;2;6;14
110402;2;187;12
110401;2;44;14
110402;2;123;15
110401;2;9470;12
110403;2;37;11
110502;2;2;10
110502;2;6;18
110502;2;187;11
110501;2;44;12
110502;2;123;14
110501;2;9470;12
110503;2;37;19

Je voudrais faire la moyenne de ecartype, en regroupant sur trn et sur la date, de manière prendre en compte 2 mois consécutif (soit 1104 et 1105)
donc pour trn = 2 , la moyenne de ecartype pour la période 1104-1105 est 11.

Ici mon exemple de comprend que 2 mois, mais ma base à un historique de 3ans.

J'ai pensé à passer par des substring et des case afin de découper les dates et dire que 1104 correspond à 1105 par exemple; mais n'y a t il pas plus simple?

Merci d'avance

Hors ligne

#2 21/06/2011 06:44:01

Marc Cousin
Membre

Re : Requete de regroupement

Si vous êtes en 8.4 ou plus, vous devriez pouvoir faire ça avec une window function, de façon raisonnablement simple: http://docs.postgresql.fr/9.0/tutorial-window.html


Marc.

Hors ligne

#3 21/06/2011 08:28:49

damalaan
Membre

Re : Requete de regroupement

ah je les avais oublié ces fonctions!! elles m'ont pourtant déjà sorti de l'impasse dans cette bdd!!

mes pseudo dates sont donc au format AAMMDD, où DD est la décade donc toujours égal à 01, 02 ou 03
néanmoins je n'arrive pas à trouver un modele mathématique pour regrouper 2 mois

la logique est la suivante pour regrouper 2 mois:
101201 à 110103
110201 à 110303
110401 à 110503
110601 à 110703
etc

Hors ligne

#4 21/06/2011 09:57:49

SQLpro
Membre

Re : Requete de regroupement

Il suffit de créer une table de regroupement ou bien d'utiliser une CTE pour simuler cette table.

Exemple :

WITH T_GROUP AS
(SELECT 1 AS GROUPE, '101201' AS DEBUT, '110103' AS FIN
 UNION ALL
 SELECT 2 AS GROUPE, '110201' AS DEBUT, '110303' AS FIN
 UNION ALL
 SELECT 3 AS GROUPE, '110401' AS DEBUT, '110503' AS FIN
 UNION ALL
 SELECT 4 AS GROUPE, '110601' AS DEBUT, '110703' AS FIN)
SELECT ...
FROM   MaTable AS T
               INNER JOIN T_GROUP  AS G
                     ON T."date" BETWEEN G.DEBUT AND G.FIN
GROUP  BY GROUPE

NOTA : il n'est pas sain d'intitulé un identifiant SQL (nom de table, de colonne...) par un mot clef de SQL comme DATE. Vous allez au devant de problèmes....

A +

Dernière modification par SQLpro (21/06/2011 09:58:15)


Frédéric Brouard, alias SQLpro,  ARCHITECTE DE DONNÉES,  Expert langage SQL
Le site sur les SGBD relationnel et langage SQL   : http://sqlpro.developpez.com/
Modélisation de données, conseil, expertise, audit, optimisation, tuning, formation
* * * * *  Enseignant CNAM PACA, ISEN Toulon,  CESI Aix en Provence  * * * * *

Hors ligne

#5 22/06/2011 08:08:29

damalaan
Membre

Re : Requete de regroupement

voici la requete finale :

CREATE OR REPLACE VIEW view_moy_labo2 AS 
 WITH t_group AS (
                (        (        (        (         SELECT 1 AS groupe, 100601 AS debut, 100703 AS fin
                                        UNION ALL 
                                                 SELECT 2 AS groupe, 100801 AS debut, 100903 AS fin)
                                UNION ALL 
                                         SELECT 3 AS groupe, 101001 AS debut, 101103 AS fin)
                        UNION ALL 
                                 SELECT 4 AS groupe, 101201 AS debut, 110103 AS fin)
                UNION ALL 
                         SELECT 5 AS groupe, 110201 AS debut, 110303 AS fin)
        UNION ALL 
                 SELECT 6 AS groupe, 110401 AS debut, 110503 AS fin
        )
 SELECT g.debut, g.fin, t.trn_esp, avg(t.stddev) AS avg
   FROM view_ecart_type_tournee t
   JOIN t_group g ON t.trn_date_prel >= g.debut AND t.trn_date_prel <= g.fin
  GROUP BY g.debut, g.fin, t.trn_esp, g.groupe
  ORDER BY t.trn_esp, g.debut;

Il ne me reste plus qu'à la construire dynamiquement!

J'ai remarqué que PostgreSQL (à moins que ce soit pgAdmin) convertit le BETWEEN en >= et <= !


Merci

Hors ligne

#6 22/06/2011 17:19:53

SQLpro
Membre

Re : Requete de regroupement

1) vous aurez sans doutes de meilleures performances si vous utilisez une table plustôt que les UNION
2) vous n'avez pas besoin d'autant de parenthèses
3) pour le BETWEEN, c'est un comportement standard pour rendre le prédicat sargable.

A +


Frédéric Brouard, alias SQLpro,  ARCHITECTE DE DONNÉES,  Expert langage SQL
Le site sur les SGBD relationnel et langage SQL   : http://sqlpro.developpez.com/
Modélisation de données, conseil, expertise, audit, optimisation, tuning, formation
* * * * *  Enseignant CNAM PACA, ISEN Toulon,  CESI Aix en Provence  * * * * *

Hors ligne

Pied de page des forums