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

MS SQL Server Discussion :

Repartion d'une période par mois


Sujet :

MS SQL Server

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2011
    Messages : 9
    Points : 3
    Points
    3
    Par défaut Repartion d'une période par mois
    Bonjour,

    j'aimerais trouver un sql permettant de décomposer une période entre une date de début et une date de fin par mois;

    exemple


    id date_deb date_fin qty par jour
    1 5/1/2013 13/3/2013 30
    2 29/01/2013 10/02/2013 10=> deviendrait

    id date_deb date_fin nb_jour qty_par_jour qty periode
    1 1/1/2013 31/01/2013 27 30 810
    1 1/2/2013 28/02/2013 28 30 840
    1 1/3/2013 31/03/2013 13 30 390
    2 1/1/2013 31/01/2013 2 10 20
    2 1/2/2013 28/02/2013 10 10 100merci de votre aide,

    bien à vous,

  2. #2
    Membre actif
    Avatar de EtherOS
    Homme Profil pro
    Etudiant Polytechnicien
    Inscrit en
    Juillet 2012
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Etudiant Polytechnicien
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2012
    Messages : 58
    Points : 233
    Points
    233
    Par défaut slt
    veillez afficher ce que vous avez fait ? le but de ce forum est de vous aider et non de bombarder des sources .Relisez bien les règles du forum .

    concernant votre problème je vous propose une solution
    -> créez une table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE TABLE IF NOT EXISTS  sdate (id AS INTEGER,date_deb AS DATE,date_fin AS DATE,qty_par_jour AS SMALLINT);
    puis insérez vos éléments ...
    Ensuite exécutez ce script :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT id,date_deb,date_fin,RAND(qty_par_jour) AS "nb_jour",qty_par_jour,nb_jour*qty_par_jour AS "qty_periode"
    FROM sdate
    ORDER BY id ASC;

  3. #3
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 668
    Points
    1 668
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par EtherOS Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE TABLE IF NOT EXISTS  sdate (id AS INTEGER,date_deb AS DATE,date_fin AS DATE,qty_par_jour AS SMALLINT);
    Sauf erreur de ma part il ne s'agit pas d'une syntaxe correcte SQL Server. Cela semble être un truc de genre MySQL !!!
    Je te rappelle qu'ici, tu es sur le forum de SQL Server.

    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

  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 781
    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 781
    Points : 52 778
    Points
    52 778
    Billets dans le blog
    5
    Par défaut
    le plus simple est de créer une table de calendrier dans votre base et cela se réduira à de simples requêtes SQL.
    A me lire : http://sqlpro.developpez.com/cours/gestiontemps/

    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
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 668
    Points
    1 668
    Billets dans le blog
    8
    Par défaut
    En plus de la suggestion ingénieuse de SQL Pro, ci-dessous une autres solution mettant en œuvre la CTE ainsi qu'une fonction de type table ITVF

    1 - Afin d’illustrer la solution proposée, nous commençâmes par créer la table dbo.RepartitionPeriode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE dbo.RepartitionPeriode(
    	id int NOT NULL,
    	date_deb datetime NULL,
    	date_fin datetime NULL,
    	qty_par_jour int NULL,
     CONSTRAINT PK_RepartitionPeriode PRIMARY KEY CLUSTERED (id ASC) ON [PRIMARY]
    ) ON [PRIMARY]
    2 - Nous remplîmes la table avec le même jeu de données fourni par l'auteur de ce topic.
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Insert Into [dbo].[RepartitionPeriode](id, date_deb, date_fin, qty_par_jour) 
     values 
     (1, '2013-01-05T00:00:00','2013-03-13T00:00:00', 30) , 
     (2, '2013-01-29T00:00:00','2013-02-10T00:00:00', 10) ;
    Nous vérifiâmes le contenu de la table :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM dbo.RepartitionPeriode
    Résultat :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    id date_deb date_fin qty_par_jour
    1	2013-01-05 2013-03-13 30
    2	2013-01-29 2013-02-10 10
    3 - Nous créâmes une fonction de type table ITVF
    Code SQL : 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
    CREATE FUNCTION dbo.Fct_Repartition_Mensuelle(@Id Int, 
                                                  @date_deb datetime, 
                                                  @date_fin datetime )
    RETURNS TABLE
    RETURN          
        WITH CTE_Repartition_Mensuelle( Id, date_deb, date_fin, nb_jour  ) AS 
          (
                SELECT @Id AS Id, 
                       DATEADD(month, DATEDIFF(month, 0, @date_deb ), 0)  As date_deb, 
                       DATEADD (month, +1 , DATEADD(month, DATEDIFF(month, 0, @date_deb ), 0) ) - 1  AS date_fin,                    
                       CASE 
                          WHEN DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0,  @date_deb) + 1, 0)) <= @date_fin then 
                             DATEDIFF(day, @date_deb, DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0,  @date_deb) + 1, 0)) ) + 1 
                           ELSE 
                             DATEDIFF(day, @date_deb, @date_fin ) + 1      
                        END AS nb_jour 
                UNION ALL
                SELECT @Id AS Id,
                       date_fin +1 AS date_deb, 
                       DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, date_fin + 1) + 1, 0)) As date_fin,                   
                    CASE 
                       WHEN @date_fin <= DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, date_fin +1) + 1, 0)) then
                           DATEDIFF(day,  date_fin +1, @date_fin) +1
                       ELSE       
                         DATEDIFF(day, date_fin +1, 
                            DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0,  
                               DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, date_fin + 1) + 1, 0))                        
                            ) + 1, 0))
                             ) +1 
                     END  AS nb_jour
     
                FROM CTE_Repartition_Mensuelle                                              
                 WHERE date_Fin <  DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, @date_fin) + 1, 0))
          )      
          SELECT Id, date_deb, date_fin, nb_jour  FROM CTE_Repartition_Mensuelle 
    GO
    4 - Pour obtenir le résultat attendu, nous lançâmes la requête ci-dessous :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT A.id, B.date_deb, B.date_fin, B.nb_jour, A.qty_par_jour, (A.Qty_par_jour * B.nb_jour) AS Qty_Periode 
       FROM dbo.RepartitionPeriode A 
    CROSS APPLY dbo.Fct_Repartition_Mensuelle(id, date_deb, date_fin) AS B
    Résultat :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    id date_deb  date_fin nb_jour  qty_par_jour Qty_Periode
    1 2013-01-01 2013-01-31  27	30	810
    1 2013-02-01 2013-02-28  28	30	840
    1 2013-03-01 2013-03-31  13	30	390
    2 2013-01-01 2013-01-31  3         10      30
    2 2013-02-01 2013-02-28  10	10	100
    Nous constatâmes avec satisfaction que le résultat obtenu correspond bien à ce qui a été demandé.

    Remarque :
    Deux expressions T-SQL reviennet assez régulièrement il s'agit de la date de début du mois et la date de fin de mois.
    DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0) AS premier_jour_du_mois_courant
    DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, GETDATE()) + 1, 0)) AS dernier_jour_du_mois_courant
    Ces 2 expressions proviennent de l'excellent blog d'elsuket ci-dessous :
    blog.developpez.com/elsuket/p9840/snippets/trouver_le_premier_et_le_dernier_jour_de

    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

Discussions similaires

  1. Décomposer une période par mois
    Par tnguyen05 dans le forum Développement
    Réponses: 9
    Dernier message: 18/06/2013, 12h13
  2. couper une période par année
    Par 4rn0_o dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 31/07/2008, 17h05
  3. [Dates] Découpage d'une période en mois
    Par roms19 dans le forum Langage
    Réponses: 1
    Dernier message: 30/06/2008, 12h05
  4. editer une requete par mois
    Par dolphin37 dans le forum Access
    Réponses: 17
    Dernier message: 20/02/2006, 14h53
  5. Comment grouper une requête par mois ?
    Par Le Pharaon dans le forum Langage SQL
    Réponses: 6
    Dernier message: 29/06/2005, 12h01

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