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 08/02/2012 14:18:06

damalaan
Membre

Requête de regroupement sur une période glissante

Bonjour,

Je veux trouver des doublons mais 2 périodes consécutives et comme un exemple est bien mieux que ce que je n'arrive pas à expliqué :
soit les données suivantes:
esp    num    periode
1    563    1001
1    2040    1001
1    12    1001
1    123    1001
1    987    1001
1    563    1002
1    569    1002
1    12    1002
1    13    1002
1    563    1003
1    569    1003
1    2040    1003
1    12    1003
1    123    1003
1    6    1003
       
et je veux que le résultat de la requête soit ça           
résultat       
1    563    1002
1    12    1002
1    563    1003
1    569    1003
1    12    1003

en prenant la période de réf 1002 : 563 et 12 apparaissent en 1001 et 1002; pour une période de réf de 1003, 563 569 et 12 apparaissent en 1002 et 1003
on remarque aussi que 2040 est en 1001 et 1003, mais n'étant sur des périodes consécutives, il ne m'intéresse pas.

j'ai bien pensé à faire des regroupements mais je ne peux pas alors faire de période glissante

merci de votre aide

Hors ligne

#2 09/02/2012 10:18:00

Marc Cousin
Membre

Re : Requête de regroupement sur une période glissante

En fait, ce que vous cherchez, c'est à récupérer, pour une période données, les num qui sont présents à la fois dans la période et dans la période précédente, c'est bien ça ?


Marc.

Hors ligne

#3 09/02/2012 10:56:37

damalaan
Membre

Re : Requête de regroupement sur une période glissante

bonjour,

oui c'est tout à fait.
à la la lecture de votre message je viens de penser aux fonction de fenêtrage ainsi qu'à la fonction lag, que j'ai utilisé il y a qq temps mais il faut que je me remette dedans (je ne travaille malheureusement pas assez souvent sur postgresql)!!

Hors ligne

#4 09/02/2012 13:00:19

Marc Cousin
Membre

Re : Requête de regroupement sur une période glissante

Au fait, la période précédente, c'est la précédente dans ce qui est dans la table, ou la période -1 ? Autrement dit, si on avait une période 999 et une période 1001, mais pas de 1000, est-ce que 999 est la précédente de 1001 ou de 1000 ?


Marc.

Hors ligne

#5 10/02/2012 09:15:08

damalaan
Membre

Re : Requête de regroupement sur une période glissante

euh les 2 mon capitaine!!
en fait mes périodes sont la contraction de l'année et du mois donc 1001, c'est janvier 2010.
j'avoue que c'est pas top comme truc, mais les données que je reçois sont faites comme ça, et je n'ai pas ressenti le besoin de les transformer en date quand j'ai monté ma base (ceci dit il va peut être falloir y penser)
donc tant que l'on est de février à décembre, la période précédente est bien égale à période -1, il n'y a que janvier qui pose problème puisque 1001 - 1 = 0912 !!

Hors ligne

#6 10/02/2012 10:50:33

Marc Cousin
Membre

Re : Requête de regroupement sur une période glissante

Oui, je pense qu'il va falloir y penser, parce que là, on va être obligés de faire beaucoup de conversions inutiles pour trouver le lien entre 2 périodes consécutives.

Là on est obligé d'écrire une horreur de ce genre pour passer de l'intervalle au suivant : case when (periode%100)=99 then periode-99+12 else periode end from (values (999))

Bref, je l'ai presque écrit, mais à l'envers (ma requête retourne la période la plus basse des deux, pas la plus haute):

SELECT testcour.esp, testcour.num, testcour.periode from test testcour 
join (select esp,num,case when ((periode-1)%100)=99 then (periode-1)-99+12 else (periode-1) end as periode from test) as testprec 
    on testcour.periode=testprec.periode and testcour.num=testprec.num;


 esp | num | periode 
-----+-----+---------
   1 |  12 |    1001
   1 | 563 |    1001
   1 |  12 |    1002
   1 | 563 |    1002
   1 | 569 |    1002
(5 lignes)

À vous de jouer pour corriger le dernier détail smile

Dernière modification par Marc Cousin (10/02/2012 10:50:53)


Marc.

Hors ligne

#7 15/02/2012 13:45:06

damalaan
Membre

Re : Requête de regroupement sur une période glissante

Me revoilà après avoir laissé de coté mon problème pendant qq jours!

Effectivement ce n'est pas très joli tout ça!!
je voudrais donc commencer par avoir le bon format au départ!
Existe t il un format dans postgres qui correspondrait à ce que je veux (càd AAMM)?
je n'ai rien vu dans la doc
je pensais donc stocker cette donnée sous la forme aaaa-mm-01, est-ce que bonne solution?

Hors ligne

#8 15/02/2012 14:06:27

Marc Cousin
Membre

Re : Requête de regroupement sur une période glissante

Ce n'est pas une question de format mais de type. Si vous voulez stocker des données de type mois-année, stockez une date (et mettez toujours le premier jour du mois).  Ou passez par un to_date.

Par exemple:

# SELECT to_date('01-2011','MM-YYYY');
  to_date   
------------
2011-01-01


Si toutes vos dates sont stockées au 1er de chaque mois, rajouter un mois ou enlever des mois, c'est très facile:


SELECT to_date('01-2011','MM-YYYY') + '3 month'::interval;
      ?column?                                                                                                                                                                       
---------------------                                                                                                                                                               
2011-04-01 00:00:00                                                                                                                                                                 

Si après, pour l'affichage, vous voulez à nouveau votre format, repassez y en utilisant un to_char:


SELECT to_char(to_date('01-2011','MM-YYYY') + '3 month'::interval,'MMYYYY');
to_char
---------
042011

Mais je pense que stocker les données dans un type qui corresponde à la donnée que vous voulez manipuler (date, c'est juste un peu trop précis pour vos besoin, mais c'est ce qui colle le mieux), ça simplifie l'écriture, et que ça sera plus performant (les opérations entre dates et intervalles sont bien plus rapides que le case immonde que j'ai fait plus haut).

Par ailleurs, évitez les dates sur 2 chiffres. C'est pénible de gérer des dates pivot smile


Marc.

Hors ligne

#9 17/02/2012 14:55:12

SQLpro
Membre

Re : Requête de regroupement sur une période glissante

Cette requête n'est-elle pas suffisante :

CREATE TABLE T
(esp INT,
 num INT,
periode INT
) 
INSERT INTO T
VALUES 
(1, 563, 1001),
(1, 2040, 1001),
(1, 12, 1001),
(1, 123, 1001),
(1, 987, 1001),
(1, 563, 1002),
(1, 569, 1002),
(1, 12, 1002),
(1, 13, 1002),
(1, 563, 1003),
(1, 569, 1003),
(1, 2040, 1003),
(1, 12, 1003),
(1, 123, 1003),
(1, 6, 1003);


SELECT T1.periode, T1.num
FROM   T AS T1
       INNER JOIN T AS T2
             ON T1.periode = T2.periode -1
                AND T1.num = T2.num

???

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