Prendre la valeur précédente quand donnée manquante

Prendre la valeur précédente quand donnée manquante - SQL/NoSQL - Programmation

Marsh Posté le 10-04-2019 à 16:01:10    

Bonjour,
J'ai une table Historique qui contient les changements de certaines valeurs pour des personnes et qui a les champs suivantes :
ID (id de l'entrée dans historique, 1 à n)
Date (date de l'entrée dans l'historique, au format yyyy-mm-dd hh:mm:ss)
IDPersonne (ID de la personne concernée par un changement des valeurs qui viennent après)
Valeur1
Valeur2
 
Je voudrais faire une requête qui, pour chaque mois-année et chaque personne, me donne les valeurs (valeur1, valeur2...) qu'il avait à la fin du mois. J'ai fai la requête suivante :

Code :
  1. SELECT h.IDPersonne, HistoTmp.YEARMONTH, h.Valeur1 FROM Historique h, (SELECT th.IDPersonne, DATE_FORMAT(th.Date, '%Y-%m') AS YEARMONTH, MAX(th.ID) AS MaxHistoID
  2. FROM Historique th WHERE th.IDPersonne IN (1, 2, 38, 75) AND th.Date BETWEEN '2018-07-01' AND '2018-10-31'
  3. GROUP BY th.IDPersonne, YEARMONTH) AS HistoTmp
  4. WHERE h.ID= HistoTmp.MaxHistoID
  5. ORDER BY h.IDPersonne, HistoTmp.YEARMONTH


Problème : pour certaines personnes, il arrive qu'ils n'aient pas de changement de valeur dans leur historique certains mois. J'ai donc des trous. Je voudrais donc que pour les mois-années où les personnes n'ont pas d'entrée dans leur historique, ça prenne la valeur du mois précédent. Je dois avouer que je sèche. :/ Je ne veux pas passer par une procédure stockée.
 
Merci par avance pour votre aide.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 10-04-2019 à 16:01:10   

Reply

Marsh Posté le 12-04-2019 à 17:53:35    

Un petit up à tout hasard.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 12-04-2019 à 18:39:36    

Je ne m'y connais pas assez en SQL mais cela me semble impossible, cela reviendrait à "créer" des données pour le résultat.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 15-04-2019 à 19:57:32    

Est-ce que je dis une bêtise si je propose de passer par une table qui contiendrait deux champs, mois et année, pour tous les mois dont tu as besoin sur toutes les années, sur laquelle tu ferais une jointure externe pour être sûr de générer une ligne par mois, et ensuite trouver les lignes où la valeur est nulle pour la remplacer par la valeur du mois précédent ?
J'ai juste un doute sur la faisabilité en ensembliste, du coup je ne suis pas sûr que ça puisse se faire, mais il me semble que tu m'avais aidé sur un problème "semblable" il y a quelques années...

Reply

Marsh Posté le 15-04-2019 à 20:04:15    

Sur stackoverflow il y a un truc qui ressemble : https://stackoverflow.com/questions [...] rver-query

Reply

Marsh Posté le 15-04-2019 à 22:12:00    

J'ai fait ça vite fait :  
 

Code :
  1. SELECT C.mois, C.annee, H.id_pers, COALESCE(MAX(H.date), LAST_DAY(STR_TO_DATE(CONCAT(C.annee,' ',C.mois,' 01'), '%Y %m %d'))),
  2. (CASE WHEN H.valeur IS NULL THEN
  3.  (
  4.     SELECT CONCAT(H2.valeur, ' (s)') /*Pour les tests, j'ai mis un (s) après les valeurs simulées*/
  5.     FROM histo H2
  6.     WHERE H2.date < STR_TO_DATE(CONCAT(C.annee,' ',C.mois,' 01'), '%Y %m %d' )
  7.         AND H2.id_pers = 4
  8.     ORDER BY H2.date DESC
  9.     LIMIT 1
  10. )
  11.     ELSE
  12.  (
  13.         SELECT H3.valeur
  14.         FROM histo H3
  15.         WHERE month(H3.date) = C.mois
  16.          AND year(H3.date) = C.annee
  17.          AND H3.id_pers = 4
  18.         ORDER BY H3.date DESC
  19.         LIMIT 1
  20. )
  21.  END
  22. ) AS VALEUR
  23. FROM calendrier C
  24. LEFT OUTER JOIN histo H ON MONTH(H.date) = C.mois AND YEAR(H.date) = C.annee AND H.id_pers = 4
  25. WHERE C.annee = 2017 AND C.mois BETWEEN 1 AND 12
  26. GROUP BY C.mois, C.annee, H.id_pers
  27. ORDER BY C.annee, C.mois


 
Petit problème, je n'ai pas réussi à le faire fonctionner pour plusieurs id_pers en même temps puisque la jointure n'est pas possible (par définition, si on n'a pas de données dans la table HISTO pour un mois complet pour une personne, il n'y a pas de ligne avec cette personne)


Message édité par Tibar le 15-04-2019 à 22:25:04
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed