IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Création d'une table calendrier [2012]


Sujet :

Développement SQL Server

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juillet 2013
    Messages : 15
    Points : 21
    Points
    21
    Par défaut Création d'une table calendrier
    Bonjour,

    A des fins de recherche et de comptage j'ai besoin d'un calendrier .
    Pour cela j'utilise une table # que je créé ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    declare @DtDeb datetime = '01/09/2013 00:00:00', @DtFin datetime = '01/10/2013 00:00:00', @RegroupementCalendaire integer = 2 -- 0 jour , 1 semaine , 2 mois , 3 période complète
    declare @DateD_utc datetime = dbo.fn_LocalTimeToUTC(cast(floor(cast(@DtDeb as float)) as datetime)) -- ex : 01/07/13 00:00:00
    declare @DateF_utc datetime = dbo.fn_LocalTimeToUTC(dateadd(s, -50, dateadd(dd,+1,cast(floor(cast(@DtFin as float)) as datetime)))) -- ex : 01/07/13 23:59:10
    DECLARE @ecart int = (datepart(dy,@DateF_utc) - Datepart(DY,@DateD_utc))
    -- select @ecart
    --################################################################--
    --						 Création du calendrier					  --
    --################################################################--
    ;WITH dates(DateD,DateF) AS
    (
        SELECT	@DateD_utc as Datetime,
    			DATEADD(d,-@ecart,@DateF_utc) as Datetime
        UNION ALL
        SELECT (case
    				when (@RegroupementCalendaire=0  AND DateD < @DateF_utc) then DATEADD(d,1,DateD)
    				when (@RegroupementCalendaire=1  AND DateD < @DateF_utc) then DATEADD(WW,1,DateD)
    				when (@RegroupementCalendaire=2  AND DateD < @DateF_utc) then DATEADD(MM,1,DateD)
    				when (@RegroupementCalendaire=3 ) then @DateD_utc
    				end),
    			(case when (@RegroupementCalendaire=0  AND DateD < @DateF_utc) then DATEADD(d,1,DateF)
    				when (@RegroupementCalendaire=1  AND DateD < @DateF_utc) then DATEADD(WW,1,DateF)
    				when (@RegroupementCalendaire=2  AND DateD < @DateF_utc) then DATEADD(MM,1,DateF)
    				when (@RegroupementCalendaire=3 ) then @DateD_utc
    			end)
        FROM dates
        WHERE (case
    				when (@RegroupementCalendaire=0  AND DateD < @DateF_utc) then DATEADD(d,1,DateF)
    				when (@RegroupementCalendaire=1  AND DateD < @DateF_utc) then DATEADD(WW,1,DateF)
    				when (@RegroupementCalendaire=2  AND DateD < @DateF_utc) then DATEADD(MM,1,DateF)
    				end)  < @DtFin
    )
    SELECT
    case when DateD < @DtFin then DateD end as DtDeb,
    (case
    		when (@RegroupementCalendaire=0 AND DateD < @DateF_utc) then DATEADD(d,1,DateF)
    		when (@RegroupementCalendaire=1 AND DateD < @DateF_utc)then DATEADD(WW,1,DateF)
    		when (@RegroupementCalendaire=2 AND DateD < @DateF_utc) then DATEADD(MM,1,DateF)
    		when (@RegroupementCalendaire=3 ) then @DateF_utc
    		end)   as DtFin,
    (case
    		when (@RegroupementCalendaire=0 AND DateD < @DateF_utc) then  (CONVERT(nvarchar,DATEADD(d,1,DateD),103))
    		when (@RegroupementCalendaire=1 AND DateD < @DateF_utc) then (CONVERT(nvarchar,DATEPART(WEEK, DateD))+' - '+CONVERT(nvarchar,DATEPART(YEAR,DateD)))
    		when (@RegroupementCalendaire=2 AND DateD < @DateF_utc) then(CONVERT(nvarchar,(DATEPART(MM, DateD)))+' - '+CONVERT(nvarchar,DATEPART(YEAR,DateD)))
    		when (@RegroupementCalendaire=3 ) then CONVERT(nvarchar,'Période')  END )as Champs
    INTO #Calendar
    FROM dates
    OPTION (MAXRECURSION 0)
     
    select * from #calendar
    DROP TABLE #Calendar
    Malheureusement j'ai un problème , je choisi un regroupement par mois avec les dates indiqués dans le code et je me retrouve avec ce résultat :

    DtDeb DtFin Champs
    2013-08-31 22:00:00.000 2013-09-30 21:59:10.000 8 - 2013
    2013-09-30 22:00:00.000 2013-10-30 21:59:10.000 9 - 2013

    Je ne vois pas comment limités mes dates pour vraiment n'avoir que le mois voulu et j'aurais besoin d'un petit coup de main.

  2. #2
    Membre actif
    Avatar de SQL_EVAN
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Juillet 2011
    Messages
    161
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Thaïlande

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2011
    Messages : 161
    Points : 245
    Points
    245
    Par défaut
    Bah je pense que le problème vient du fait que vous avez choisi un type datetime.

    Vous pouvez le remplacer par le mois en faisant encapsulant et convertissant les CASE WHEN pour retourner que les moi.

    J'ai fait un exemple similaire récemment et cela pourra peut être vous aider : ici (désolé, c'est en anglais, je ne l'ai pas encore traduit )

    Si vous prenez mon exemple en sélectionnant que les champs nécessaire cela pourrait vous aider.
    "Toute technologie suffisamment avancée est indiscernable de la magie." - Arthur C. Clarke

    Evan Barke - Ingénieur d'Etudes et Développement SQL Server
    Blog SQL Server, T-SQL, SSIS, Administration www.transactivesql.com
    Twitter - TransactiveSQL
    N'oubliez pas les boutons et

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juillet 2013
    Messages : 15
    Points : 21
    Points
    21
    Par défaut
    Après avoir bien bidouillé je suis arrivé au résultat suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    declare @DtDeb datetime = '16/03/2013 00:00:00', @DtFin datetime = '06/12/2013 00:00:00', @RegroupementCalendaire integer =3-- 0 jour , 1 semaine , 2 mois , 3 période complète
    DECLARE @ecart int = (datepart(dy,@DtDeb) - Datepart(DY,@DtFin))
     
    ;WITH CALENDRIER (DateD,DateF) AS
    (
    	 SELECT	
    		@DtDeb as DateTime,
    		(case
    			when @RegroupementCalendaire=0 then DATEADD(day, +1, @DtDeb)
    			when @RegroupementCalendaire=1 then DATEADD(day, -1, DATEADD(week, DATEDIFF(week, 0, @DtDeb) + 1, 0))
    			when @RegroupementCalendaire=2 then DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, @DtDeb) + 1, 0))
    			when @RegroupementCalendaire=3 then @DtFin
    			end) as Datetime
    		UNION ALL
    		SELECT (case
    					when (@RegroupementCalendaire=0  AND DateD <= @DtFin) then DATEADD(d,1,DateD)
    					when (@RegroupementCalendaire=1  AND DateD < @DtFin) then DATEADD(WW,1,DATEADD(day,-datepart(dw,DateD)+1,DateD))
    					when (@RegroupementCalendaire=2  AND DateD < @DtFin) then DATEADD(MM,1,DATEADD(month, DATEDIFF(month, 0, DateD), 0))
    					when @RegroupementCalendaire=3  then @DtDeb
    					end),
    				(case 
    					when (@RegroupementCalendaire=0  AND DateF <= @DtFin) then DATEADD(d,1,DateF)
    					when (@RegroupementCalendaire=1  AND DateF < @DtFin) then DATEADD(WW,1,DATEADD(day, -1, DATEADD(week, DATEDIFF(week, 0, DateD) + 1, 0)))
    					when (@RegroupementCalendaire=2  AND DateF < @DtFin) then DATEADD(MM,1,DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, DateD) + 1, 0)))
    					when @RegroupementCalendaire=3  then @DtFin
    					end)
    		FROM CALENDRIER
    		WHERE case
    					when (@RegroupementCalendaire=0  AND DateD <= @DtFin) then DateF 
    					when (@RegroupementCalendaire=1  AND DateD <= @DtFin) then DateF
    					when (@RegroupementCalendaire=2  AND DateF <= @DtFin) then DateF
    					end  < @DtFin
    )
    SELECT DateD as DtDeb,
    DateF as DtFin,
    dbo.fn_localTimetoUTC(DateD) as DtDeb_UTC,
    dbo.fn_localTimetoUTC(DateF) as DtFin_UTC,
    (case
    		when (@RegroupementCalendaire=0 AND DateD <= @DtFin) then  FORMAT((CONVERT(datetime,DateD,103)),'d','fr-FR')
    		when (@RegroupementCalendaire=1 AND DateD <= @DtFin) then  CONVERT(nvarchar,DATEPART(YEAR,DateD))+' - S'+(CONVERT(nvarchar,DATEPART(WEEK, DateD)))
    		when (@RegroupementCalendaire=2 AND DateD <= @DtFin) then (CONVERT(nvarchar,(DATEPART(MM, DateD)))+' - '+CONVERT(nvarchar,DATEPART(YEAR,DateD)))
    		when (@RegroupementCalendaire=3 ) then CONVERT(nvarchar,'Période')  
    		END ) as Champs
    INTO #Calendar
    FROM CALENDRIER 
    OPTION (MAXRECURSION 0)
     
    UPDATE #Calendar SET	DtFin = @DtFin,
    						DtFin_UTC = dbo.fn_LocalTimeToUTC(@DtFin)
    WHERE #Calendar.DtFin > @DtFin
     
    SELECT * FROM #Calendar
    DROP TABLE #Calendar
    Malheureusement maintenant c'est SSRS qui n'en veux pas me disant que
    "Les types ne correspondent pas entre la partie d'ancrage et la partie récursive dans la colonne "DateD" de la requête récursive "CALENDRIER"."

    Je sais pas si je suis dans la bonne partie pour espèrer avoir une réponse ou si je devrais reposter dans la partie SSRS

  4. #4
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Cela ne répond pas spécifiquement à la question mais si vous avez déjà une table des nombres, utilisez-la pour créer votre table calendrier.

    J'ai justement rencontré le besoin de créer une table calendrier hier. Or il se trouvait que j'avais déjà une table de nombre de 1 à 9999999. J'y ai juste ajouté le 0 et j'ai ainsi pu créer très facilement un calendrier avec les dates allant du 01/01/1900 au 31/12/2100 en moins d'une seconde.

    Pour convertir un nombre en date :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CAST(CAST(@NOMBRE AS DATETIME) AS DATE)
    Je n'ai pas encore compris pourquoi on ne peut pas convertir directement un entier en date et qu'il faut passer par un datetime mais bon...
    Kropernic

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 13/11/2014, 11h57
  2. Question sur la création d'une table
    Par air dans le forum Oracle
    Réponses: 4
    Dernier message: 23/10/2005, 12h46
  3. Réponses: 4
    Dernier message: 19/10/2005, 11h26
  4. Création d'une table avec foreign key
    Par lepierre dans le forum Langage SQL
    Réponses: 5
    Dernier message: 17/09/2004, 14h20
  5. INTERBASE Création d'une table
    Par Corben dans le forum InterBase
    Réponses: 2
    Dernier message: 19/06/2004, 20h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo