Problème
Dans mon sql-server-2014 je stocke des projets dans une table avec les colonnes:Sélectionnez plusieurs lignes de Timespan
Startdate .. | Date limite .... | Nom du projet ................. | Volume
2017-02-13 | 2017-04-12 | GenerateRevenue ......... | 20.02
2017-04-02 | 2018-01-01 | BuildRevenueGenerator | 300.044
2017-05-23 | 2018-03-19 | HarvestRevenue ............ | 434.009
J'ai besoin d'un SELECT pour me donner une ligne par mois du projet pour chaque projet. les jours du mois ne doivent pas être considérés.
Date .......... | Nom du projet .................. | Volume
2017-02-01 | GenerateRevenue ......... | 20.02
2017-03-01 | GenerateRevenue ......... | 20.02
2017-04-01 | GenerateRevenue ......... | 20.02
2017-04-01 | BuildRevenueGenerator | 300.044
2017-05-01 | BuildRevenueGenerator | 300.044
2017-06-01 | BuildRevenueGenerator | 300,044
...
extra
Idéalement la logique du SELECT me permet à la fois de calculer le volume mensuel ainsi que la différence entre chaque mois et le précédent.
Date .......... | Nom du projet .................. | VolumeMonthly
2017-02-01 | GenerateRevenue ......... | 6.6733
2017-03-01 | GenerateRevenue ......... | 6.6733
2017-04-01 | GenerateRevenue ......... | 6.6733
2017-04-01 | BuildRevenueGenerator | 30.0044
2017-05-01 | BuildRevenueGenerator | 30.0044
2017-06-01 | BuildRevenueGenerator | 30,0044
...
aussi ...
Je sais que je peux la carte sur une table de calendrier temporaire, mais qui tend à se ballonnement et complexe très rapide. Je cherche vraiment une meilleure façon de résoudre ce problème.
Solution
solution Gordons a travaillé très bien et il ne nécessite pas une seconde table ou la cartographie sur un calendrier quelconque. Bien que je devais changer quelques choses, comme s'assurer que les deux côtés de l'union ont le même SELECT.
Voici ma version adaptée:
with cte as (
select startdate as mondate, enddate, projectName, volume
from projects
union all
select dateadd(month, 1, mondate), enddate, projectName, volume
from cte
where eomonth(dateadd(month, 1, mondate)) <= eomonth(enddate)
)
select * from cte;
volume peut être réalisé mensuellement par le remplacement de volume avec:
CAST(Cast(volume AS DECIMAL)/Cast(Datediff(month,
startdate,enddate)+ 1 AS DECIMAL) AS DECIMAL(15, 2))
END AS [volumeMonthly]
Je recommande les étapes de bébé. –
Des exemples de données et les résultats souhaités aideraient. Vous devriez également simplifier la question. –
Merci Gordon, vous avez raison. J'ai ajouté quelques exemples de données comme vous l'avez suggéré. – LeComte