Définir les bloc de jours qui se suivent
-
mercredi 21 mars 2012 12:43Bonjour,
j'utilise SQL server 2008 et je souhaiterai effectuer l'opération suivante :
- A partir d'une liste de date du même mois je souhaiterai récupérer la date de début et la date de fin d'un bloc de jour qui se suivent (en tenant compte des week end et des jours fériés).
exemple :
01/03/2012, 02/03/2012, 05/03/2012, 06/03/2012, 20/03/2012
=> le résultat attendu est : deux blocs, le 1er ayant comme date de début 01/03/2101, date de fin : 06/03/2012 (week end pris en compte).
Le 2eme bloc ayant date de début 20/03/2012 et date de fin 20/03/2012.
est il possible de réaliser cette requete en sql ?
Merci d'avance
Toutes les réponses
-
mercredi 21 mars 2012 15:50
-- Table des intervalles CREATE TABLE INTERVAL (IntervalDebut DATETIME, IntervalFin DATETIME, NumInterval INT) -- Remplissage de la table des intervales DECLARE @DATEDEBUT DATETIME = '20120301' -- J'ai positionné la date de début sur le 01 mars 2012 DECLARE @ID_INTERVAL INT = 1 WHILE @DATEDEBUT < '20120401' BEGIN INSERT INTERVAL (IntervalDebut,IntervalFin,NumInterval) VALUES (@DATEDEBUT,DATEADD(day,7,@DATEDEBUT),@ID_INTERVAL) SET @DATEDEBUT = DATEADD(day,8,@DATEDEBUT); SET @ID_INTERVAL = @ID_INTERVAL +1 END -- Table des listes de dates CREATE TABLE LIST_DATE(colDate DATETIME) INSERT INTO LIST_DATE VALUES ('20120301'),('20120302'),('20120305'),('20120306'),('20120320') -- Affichage des dates par intervale SELECT i.IntervalDebut,i.IntervalFin,i.NumInterval,l.colDate FROM LIST_DATE l INNER JOIN INTERVAL i ON i.IntervalDebut < l.colDate AND i.IntervalFin > l.colDate
Etienne ZINZINDOHOUE - http://blog.developpez.com/zinzineti/
-
mercredi 21 mars 2012 16:22
Merci pour ta réponse,
peux être que je me suis mal exprimé,,,
je défini un bloc comme étant une succession de date, je redonne un autre exemple plus parlant :
j ai la liste de date suivante :
09/03/2012, 10/03/2012, 11/03/2012, 12/03/2012, 14/03/2012, 16/03/2012
=> le résultat est 3 bloc :
- le 1er bloc du 09 au 12 (le week end ne casse pas la notion de bloc vu que les jours se suivent, ça aurait été le cas si j'avais un jour férie)
-le 2eme bloc du 14 au 14
-le 3eme bloc du 16 au 16
Merci encore pour ton aide
-
vendredi 23 mars 2012 09:37
Bonjour, Ours_blanc,
Pouvez-vous svp nous expliquer qu’est-ce que vous voulez dire par blocs ? Ce n’est pas clair quel est le format du résultat et où est ce résultat stocké (dans une table ? dans un variable ?).
Bonne journée,
Cipri
Ciprian DUDUIALA, MSFT  
•Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.
-
vendredi 23 mars 2012 11:05
Bjr Ciprian,
Merci pour ton retour,
le résultat attendu est une table.
j'ai une liste de dates du même mois, je souhaiterai regroupé ces date par bloc,
un bloc est défini comme étant une suite de dates (Day qui se succède : la différence entre deux date = 1 day)
il faut noté aussi que le week end ou les un jour férié ne casse pas cette notion de bloc
je re explique mon exemple(vu plus haut) : supposant qu' on a la liste suivante
ven 09/03/2012, sam 10/03/2012, dim 11/03/2012, lun 12/03/2012, mer 14/03/2012, ven 16/03/2012
le premier bloc commence le 09/03 et se termine le 12/03 : remarque que le week end 10, 11 n'a pas cassé ce bloc
les deux jours qui reste ne forme pas un seul bloc puisque y'a un creux entre les deux (le 15) => ce sont deux bloc différents,
ça aurait été un seul bloc si le 15/03 étais un jour férié.
donc résultat final => 3 bloc
1er Bloc : date debut = 09/03/2012, datefin = 12/03/2012
2eme Bloc : date debut = 14/03/2012, datefin = 14/03/2012
3eme Bloc : date debut = 16/03/2012, datefin = 16/03/2012
je ne sais si je suis clair ou pas
Merci d'avance
-
vendredi 23 mars 2012 13:43
Voila la solution pour ceux qui sont intéressé, il faut utiliser les curseurs,
Solution : (Pour vérifier les jours férié j'ai créer une table qui s'appelle T_NOTWORKED qui contient la liste des jours fériés)
Create procedure test
AS
BEGIN
Declare @idxDate as smalldatetime
Declare @precDate as smalldatetime
Declare @blockStartDate as smalldatetime
Declare @nbDaysOff as tinyint
-- pour les besoins de manipulation de date on fixe le 1er jour de la semaine au lundi
SET DATEFIRST 1
--Exemple : je remplie la table qui contient une liste de date
CREATE TABLE #ListeDays(IMP_DATE smalldatetime)
insert into #ListeDays values('2012-03-09')
insert into #ListeDays values('2012-03-10')
insert into #ListeDays values('2012-03-11')
insert into #ListeDays values('2012-03-12')
insert into #ListeDays values('2012-03-14')
insert into #ListeDays values('2012-03-16')
--Création de la table resultat temporaire
CREATE TABLE #CONGES(
DATE_DEBUT datetime,
DATE_FIN datetime
)
-- on récupère la liste des CP ou RTT
Declare cursConges Cursor For
Select IMP_DATE
From #ListeDays
order by IMP_DATE
Open cursConges
Fetch Next From cursConges Into @idxDate
-- init des bornes de tests de continuité
Select @blockStartDate = @idxDate, @precDate = @idxDate
While @@FETCH_STATUS = 0
Begin
-- on vérifie la continuité des dates
If Day(@idxDate - @precDate)-1 <= 1
Set @precDate = @idxDate
Else
Begin
-- on vérifie si les journées de l'écart sont un we ou des jours férié
While Day(@idxDate - @precDate) >= 2
Begin
Set @precDate = @precDate + 1
If DatePart("dw", @precDate) <= 5 And Not Exists(Select NWO_DATE From T_NOTWORKED Where NWO_DATE = @precDate)
break
Else
Set @nbDaysOff = @nbDaysOff+1
End
End
-- on vérifie s'il y a eu un écart de date
If Day(@idxDate - @precDate) > 1
Begin
Insert Into #CONGES Select @blockStartDate, @precDate-1-@nbDaysOff
Select @blockStartDate = @idxDate, @precDate = @idxDate
End
Set @nbDaysOff = 0
Fetch Next From cursConges Into @idxDate
End
Close cursConges
Deallocate cursConges
-- on ajoute éventuellement le dernier bloc
if @blockStartDate <= @idxDate
Insert Into #CONGES Select @blockStartDate, @idxDate
-- on renvoie les résultats
SELECT * FROM #CONGES
-- on supprime la table temporaire
Drop Table #CONGESEND
- Marqué comme réponse Ciprian Duduiala vendredi 23 mars 2012 13:47
-
vendredi 23 mars 2012 13:43
Bonjour,
Bon, mais vu que les jours fériés sont différents d’un pays à l’autre et d’un an à l’autre il faut gérer cet aspect (dans une table ou par une fonction – voir aussi cette question). Comment pensez-vous le faire ?
Il faut aussi gérer la liste des dates. Vous utilisez un string avec les dates séparées par ‘,’ donc vous pouvez utiliser les solutions proposées dans cette discussion ou dans cette discussion.
Pour les week-ends c’est facile : vous pouvez utiliser la fonction DATEPART avec l’option weekday. Puis, pour voir si deux dates consécutives dans votre liste sont dans le même bloc utilisez DATEPART avec day : si les jours sont consécutifs c’est le même bloc, sinon il faut vérifier si les dates sont séparées par un week-end (avec weekday) ou par un jour férié.
Bonne journée,
Cipri
Ciprian DUDUIALA, MSFT  
•Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.
-
vendredi 23 mars 2012 13:47
Re-Bonjour,
On a écrit presque dans le même temps. J Merci pour avoir partagé avec nous la solution !
Bonne journée,
Cipri
Ciprian DUDUIALA, MSFT  
•Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.
-
vendredi 23 mars 2012 13:51
Merci à toi également.
Bonne journée


