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 :

Fonction pour calculer la différence entre deux dates à base 360j


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 80
    Points : 54
    Points
    54
    Par défaut Fonction pour calculer la différence entre deux dates à base 360j
    Bonjour,
    Svp je veux une fonction qui calcule la différence entre deux dates et qui retourne le résultat en jours
    exp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    '20/03/2014'-'01/02/2015'=312
    Remarque : les deux dates sont ajoutées au calcule cad
    mois de mars=11 jours
    mois avril 2014 JUSQU'A 30/01/2015=10*30=300
    mois de fevrier=1 jour
    Total= 312 jours
    ps mois=30 jours

    Merci d'avance

  2. #2
    Invité
    Invité(e)

  3. #3
    Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 80
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par 7gyY9w1ZY6ySRgPeaefZ Voir le message
    Je vous remercie pour votre reponse mais le resultat du
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select DATEDIFF(DAY,'20/03/2014','01/02/2015')
    est 318 alors moi je veux 312 A BASE DE 360 (1 mois =30 jours)

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 768
    Points : 52 719
    Points
    52 719
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par messi1987 Voir le message
    Bonjour,
    Svp je veux une fonction qui calcule la différence entre deux dates et qui retourne le résultat en jours
    exp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    '20/03/2014'-'01/02/2015'=312
    Remarque : les deux dates sont ajoutées au calcule cad
    mois de mars=11 jours
    mois avril 2014 JUSQU'A 30/01/2015=10*30=300
    mois de fevrier=1 jour
    Total= 312 jours
    ps mois=30 jours

    Merci d'avance
    Le mieux est toujours d'implémenter une table de date telle que je le préconise dans cet article : http://sqlpro.developpez.com/cours/gestiontemps/
    Par exemple pour votre cas précis :
    La table des dates :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE T_DAT
    (DAT_DATE                 DATE                                PRIMARY KEY,
     DAT_AN                   AS CAST(YEAR(DAT_DATE) AS SMALLINT) PERSISTED,
     DAT_MOIS                 AS CAST(MONTH(DAT_DATE) AS TINYINT) PERSISTED,
     DAT_JOUR                 AS CAST(DAY(DAT_DATE) AS TINYINT)   PERSISTED,
     DAT_NB_JOUR_FIN_MOIS     TINYINT ,
     DAT_JOUR_FIN_MOIS        TINYINT
    )
    Remplissage de la table avec date de 2000 à 2100 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SET NOCOUNT ON;
    DECLARE @D DATE
    SET @D = '2000-01-01'
    WHILE @D < '2100-12-31'
    BEGIN
       INSERT INTO T_DAT (DAT_DATE) VALUES (@D);
       SET @D = DATEADD(day, 1, @D)
    END;
    GO
    Mise à jour des colonnes pour nos calculs :
    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
    WITH T0 AS
    (
    SELECT DAT_DATE, ROW_NUMBER() OVER(PARTITION BY DAT_AN, DAT_MOIS ORDER BY DAT_JOUR DESC) - 1 AS NB_JOUR_FIN_MOIS
    FROM   T_DAT
    )
    UPDATE T
    SET    DAT_NB_JOUR_FIN_MOIS = NB_JOUR_FIN_MOIS
    FROM   T_DAT AS T
           INNER JOIN T0 
                 ON T.DAT_DATE = T0.DAT_DATE;
    GO
    UPDATE T
    SET    DAT_JOUR_FIN_MOIS = T2.DAT_JOUR 
    FROM   T_DAT AS T
           INNER JOIN T_DAT AS T2
                 ON T.DAT_AN = T2.DAT_AN
                 AND  T.DAT_MOIS = T2.DAT_MOIS
                 AND T2.DAT_NB_JOUR_FIN_MOIS = 0
    GO
    Création de la fonction de calcul à jours de 30 mois :
    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
    CREATE FUNCTION F_MOIS30 (@D1 DATE, @D2 DATE)
    RETURNS INT
    AS
    BEGIN
       DECLARE @AN INT, @MOIS INT, @JFM INT
     
       SELECT @AN = DAT_AN, @MOIS = DAT_MOIS, @JFM = DAT_NB_JOUR_FIN_MOIS
       FROM   T_DAT 
       WHERE DAT_DATE = @D1;
     
       SELECT @AN = DAT_AN - @AN, @MOIS = DAT_MOIS - @MOIS, @JFM = @JFM + DAT_JOUR
       FROM   T_DAT 
       WHERE DAT_DATE = @D2;
     
       RETURN (@AN * 12 + @MOIS - 1) * 30 + @JFM
    END;
    GO
    Exemple d'utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT dbo.F_MOIS30('2014-03-20', '2015-02-01')
    Tout cela est bien entendu à tester !!!!

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    ou bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    declare @debut DATE = '2014-03-20'
    declare @fin DATE = '2015-02-01'
     
    SELECT DATEDIFF(MONTH, @debut, @fin) * 30 + 1 - DAY(@debut) + DAY(@fin)

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur Full-stack
    Inscrit en
    Novembre 2010
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Full-stack

    Informations forums :
    Inscription : Novembre 2010
    Messages : 372
    Points : 489
    Points
    489
    Par défaut
    Bonjour,

    Avec le code précédent transformé en fonction tu auras ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    CREATE FUNCTION dbo.CalculJourCompable
     (@debut DATE ,
     @fin DATE ) RETURNS NVARCHAR(11)
     AS
     BEGIN
    	DECLARE @Resultat int
    	DECLARE @ResultatFinal nvarchar(11)
     
    		set @Resultat = (SELECT DATEDIFF(MONTH, @debut, @fin) * 30   - DAY(@debut) + DAY(@fin))
    		Set @ResultatFinal = cast (@Resultat as nvarchar(5))	+ ' Jours'
     
    		return @ResultatFinal 
     END
    A l'exécution tu fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Select dbo.CalculJourCompatable ('2014-03-20','2015-02-01')
    Au cas le résultat en type int, la fonction sera comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    CREATE FUNCTION dbo.CalculJourCompable
     (@debut DATE ,
     @fin DATE ) RETURNS int
     AS
     BEGIN
    	DECLARE @Resultat int
     
    		set @Resultat = (SELECT DATEDIFF(MONTH, @debut, @fin) * 30   - DAY(@debut) + DAY(@fin))
     
    		return @Resultat
     END
    A l'exécution tu fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Select dbo.CalculJourCompatable ('2014-03-20','2015-02-01')
    Merci
    La recherche de la connaissance est une Lumière qui apaise le Cœur.
    Si une réponse vous a été utile , n'oubliez pas de voter en cliquant sur:.

  7. #7
    Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 80
    Points : 54
    Points
    54
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Bonjour,

    ou bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    declare @debut DATE = '2014-03-20'
    declare @fin DATE = '2015-02-01'
     
    SELECT DATEDIFF(MONTH, @debut, @fin) * 30 + 1 - DAY(@debut) + DAY(@fin)
    JE VOUS remercie SQLpro ,aieeeuuuuu,alexandre le grand pour vos réponses très intéressantes.
    @aieeeuuuuu le problème dans ce calcule se trouve dans les cas particuliers :
    par example si on fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    declare @debut DATE = '2014-03-01'
    declare @fin DATE = '2014-03-31'
     
    SELECT DATEDIFF(MONTH, @debut, @fin) * 30 + 1 - DAY(@debut) + DAY(@fin)
    Alors le resultat est 31 jours cad il faut ajouter des conditions si datepart(month,@debut)=datepart(month,@fin) and DATEDIFF(day, @debut, @fin) =31 THEN resultat=30
    IL Y A aussi le cas du mois de fevrier qui a 28 ou 29 jours
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    declare @debut DATE = '2014-01-01'
    declare @fin DATE = '2014-02-28'
     
    SELECT DATEDIFF(MONTH, @debut, @fin) * 30 + 1 - DAY(@debut) + DAY(@fin)
    le résultat est 58 jourS alors que normalement c'est 60 jours

    j'aimerai comprendre la solution de M.SQLpro parce que je la trouve intéressante

  8. #8
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 768
    Points : 52 719
    Points
    52 719
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par messi1987 Voir le message
    j'aimerai comprendre la solution de M.SQLpro parce que je la trouve intéressante
    Et bien venez à un de mes cours, par exemple PAV chez Orsys : http://www.orsys.fr/formation-sql-se...ql-avancee.asp

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  9. #9
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par messi1987 Voir le message
    @aieeeuuuuu le problème dans ce calcule se trouve dans les cas particuliers :
    En effet, mais dans votre cas, vous aurez toujours forcément des cas particuliers. Car ici, n'en déplaise à Aristote, le tout est inférieur à la somme des parties.

    On pourrait par exemple ajouter un jour à la date de fin dans le code que j'ai donné :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT DATEDIFF(MONTH, @debut, DATEADD(DAY, 1,@fin)) * 30 - DAY(@debut) + DAY(DATEADD(DAY, 1,@fin))
    Ce qui donne les résultats voulus pour les exemples que vous avez donnés. Mais on se retrouve alors avec d'autres aberrations :
    Si on reprend votre exemple du mois de février : vous voulez comptabiliser 60 jours entre le 1er janvier et le 28 fevrier. Soit !
    Mais si on enlève un seul jours à la borne de fin, soit le 27 février, on tombe alors sur 57 jour d'écart, ce qui donne
    Donc, il vous faut en premier lieu identifier précisément tous les cas particuliers, et définir les règles de gestion qui permettent de faire rentrer un peu plus de 365 jours dans 360 !

  10. #10
    Membre confirmé
    Homme Profil pro
    Développeur Full-stack
    Inscrit en
    Novembre 2010
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Full-stack

    Informations forums :
    Inscription : Novembre 2010
    Messages : 372
    Points : 489
    Points
    489
    Par défaut
    Bonjour,

    Essaie cette procédure stockée:

    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
     
    CREATE PROC CalculJours (@debut DATE ,
     @fin DATE )
     AS
     BEGIN
    	--Vérifie année bissextile
    	IF(((SELECT ISDATE(CAST(YEAR(@fin)AS nvarchar(04)) + '0229') )=1) AND (SELECT (MONTH(@fin)))= 2)
    		BEGIN
    			IF((SELECT (DAY(@fin)))<>29)
    				SELECT DATEDIFF(MONTH, @debut, @fin) * 30 +1 - DAY(@debut) + DAY(@fin)
    			ELSE
    				SELECT DATEDIFF(MONTH, @debut, @fin) * 30 + 1
    		END
    	ELSE 
     
    			SELECT DATEDIFF(MONTH, @debut, @fin) * 30 + 1 - DAY(@debut) + DAY(@fin)
     
     END
    MERCI
    La recherche de la connaissance est une Lumière qui apaise le Cœur.
    Si une réponse vous a été utile , n'oubliez pas de voter en cliquant sur:.

  11. #11
    Membre confirmé
    Homme Profil pro
    Développeur Full-stack
    Inscrit en
    Novembre 2010
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Full-stack

    Informations forums :
    Inscription : Novembre 2010
    Messages : 372
    Points : 489
    Points
    489
    Par défaut
    Citation Envoyé par messi1987 Voir le message
    Bonjour,
    Svp je veux une fonction qui calcule la différence entre deux dates et qui retourne le résultat en jours
    exp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    '20/03/2014'-'01/02/2015'=312
    Remarque : les deux dates sont ajoutées au calcule cad
    mois de mars=11 jours
    mois avril 2014 JUSQU'A 30/01/2015=10*30=300
    mois de fevrier=1 jour
    Total= 312 jours
    ps mois=30 jours

    Merci d'avance
    C'est d'ici que viens l'erreur, il n'y a pas 312 jours entre les 2 dates, mais plutôt 311 jours. Le mois de Mars est parcouru à hauteur de 10 jours non pas 11. Les 2 extrémités de dates à savoir, '20/03/2014' et '01-04-2015' sont exclues du décompte. Donc la solution de SQLPro est bonne, et le code précédent que je viens de modifier, deviendra comme suit:

    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
     
     
    CREATE PROC CalculJours (@debut DATE ,
     @fin DATE )
     AS
     BEGIN
    	--Vérifie année bissextile
    	IF(((SELECT ISDATE(CAST(YEAR(@fin)AS nvarchar(04)) + '0229') )=1) AND (SELECT (MONTH(@fin)))= 2)
    		BEGIN
    			IF((SELECT (DAY(@fin)))<>29)
    				SELECT DATEDIFF(MONTH, @debut, @fin) * 30 - DAY(@debut) + DAY(@fin)
    			ELSE
    				SELECT DATEDIFF(MONTH, @debut, @fin) * 30 
    		END
    	ELSE 
     
    			SELECT DATEDIFF(MONTH, @debut, @fin) * 30  - DAY(@debut) + DAY(@fin)
     
     END
    Au cas où, tu ajouterais l'une ou ces 2 dates, il te faudrait ajouter le nombre correspondant en calcul.
    La recherche de la connaissance est une Lumière qui apaise le Cœur.
    Si une réponse vous a été utile , n'oubliez pas de voter en cliquant sur:.

  12. #12
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par Alexandre le Grand Voir le message
    Donc la solution de SQLPro est bonne, ...
    NB
    Avec cette fonction :

    la différence entre A et B n'est pas toujours égale à -(différence entre B et A)
    la différence entre A et A varie entre -2 et +1...

Discussions similaires

  1. [AC-2003] Calcul de différence entre deux dates : problème de format
    Par sinifroth dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 22/01/2010, 15h35
  2. Calcul de différence entre deux dates cas vaut 0
    Par zanoubya dans le forum Débuter
    Réponses: 3
    Dernier message: 25/12/2008, 19h45
  3. Réponses: 3
    Dernier message: 19/09/2008, 10h35
  4. Calculer la différence entre deux dates
    Par drthodt dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 18/12/2007, 08h27
  5. Requête pour calculer le temps entre deux dates
    Par Badboy62cfp dans le forum Access
    Réponses: 2
    Dernier message: 19/05/2006, 13h50

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