2
votes

Obtenir la dernière ligne pour des dates données si la date n'existe pas

Comment pouvons-nous interroger un ensemble d'enregistrements pour obtenir des données pour des dates particulières où il peut y avoir des lacunes dans les dates.

Exemple de données

date       | Price
------------------
2018-03-31 | 115
2017-03-31 | 117
2016-12-31 | 143
2015-12-31 | 110

Données requises pour les dates: 2018-03-31, 2017-03-31, 2016-12-31, 2015-12-31

date       | Price
------------------
2018-03-31 | 115
2018-03-29 | 114
2018-03-28 | 113
...
2017-03-29 | 117
2017-03-28 | 118
...
2016-12-30 | 143
2016-12-29 | 140
...
2015-12-31 | 110
2015-12-30 | 111


6 commentaires

Cela ressemble à une combinaison de l'instruction GROUP BY pour obtenir le dernier prix et de l'opérateur IN pour sélectionner les dates spécifiques


Quelle est la forme des Données requises pour les dates ? Une table d'entrée (tableau de date), une chaîne de valeurs de date séparées?


L'entrée @ PhamX.Bach est un tableau de dates.


Et quelle est la logique derrière la sortie souhaitée? Pour obtenir le prix maximum par rapport à la fin de mois spécifiques d'années spécifiques ou je l'ai manqué?


@codtex semble que si la date exacte n'est pas présente, revenir à la date antérieure la plus proche.


La sortie @SalmanA ressemble à ce que vous avez dit et je suppose que c'est la logique de l'OP. Votre solution à cet effet est très propre et belle.


3 Réponses :


0
votes

Il semble que vous ayez besoin du prix maximum pour l'année

select max(date), max(price)
from my_table  m 
inner join  (

  select max(date), year(date) my_year
  from my_table 
  group by year(date) 

) t on t.my_year = year(m.date) 
group by year(m.date)


0 commentaires

2
votes

Vous pouvez le faire avec une sous-requête corrélée. Ce qui suit renverra le prix pour la date exacte ou la date antérieure la plus proche:

SELECT dates.dt, (
    SELECT price
    FROM t
    WHERE date <= dates.dt
    ORDER BY date DESC
    LIMIT 1
) AS price
FROM (
    SELECT '2018-03-31' AS dt UNION ALL
    SELECT '2017-03-31' UNION ALL
    SELECT '2016-12-31' UNION ALL
    SELECT '2015-12-31'
) AS dates

Démo sur db fiddle


3 commentaires

Ce sera assez lent par rapport à l'opérateur IN .


@iamrajshah comment le feriez-vous exactement avec l'opérateur IN ?


@SalmanA C'est très très intelligent et efficace. J'ai appris un nouveau hack à boucler en SQL. Merci pour cela.



1
votes

Vous pouvez utiliser la fonction MySQL Last day et date_format pour obtenir le résultat souhaité. Consultez la requête: -

select last_day(a11.d_date), a11.price
from test a11
join
(select MAX(d_date) d_date, DATE_FORMAT(d_date, "%M %Y")
from test
group by DATE_FORMAT(d_date, "%M %Y")
) a12
on a11.d_date = a12.d_date

SQL Fiddle a >


0 commentaires