Vous n'êtes pas identifié(e).
Pages : 1
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
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
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
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
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
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
Dernière modification par Marc Cousin (10/02/2012 10:50:53)
Marc.
Hors ligne
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
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
Marc.
Hors ligne
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
Pages : 1