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 :

Eclater une table à une dimension inférieure


Sujet :

MS SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    365
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 365
    Par défaut Eclater une table à une dimension inférieure
    Bonjour,
    J'ai une table VENTES créée ainsi :

    WEEK-------ARTICLE----VENTES
    20050101---article1--------14
    20050101---article2--------28
    20050108---article1--------14
    20050108---article2--------28



    Je voudrais éclater la table en jours, pout avoir par exemple :
    pour la ligne1 --> 7 enregistrements :

    WEEK-------ARTICLE----VENTES
    20050101---article1--------14

    deviendrait

    DAY--------ARTICLE----VENTES
    20050101---article1--------2 (14/7)
    20050102---article1--------2 (idem..)
    20050103---article1--------2
    20050104---article1--------2
    20050105---article1--------2
    20050106---article1--------2
    20050107---article1--------2


    ainsi de suite..


    ya t il un moyen simple de faire ceci en SQL (sql server)..?
    Merci

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Bonsoir,

    Avec une procédure stockée par exemple :

    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
    54
    55
    56
    57
    58
    59
    60
    61
    CREATE PROCEDURE [dbo].[spTOTO]
    	@_dtDateDebut DATETIME,
    	@_dtDateFin DATETIME
    AS
    BEGIN
    	SET NOCOUNT ON
     
    	-- Table de la liste des jours
    	DECLARE @Tb TABLE
    	(
    		dtJour DATETIME,
    		nSemaine TINYINT
    	)
     
    	DECLARE @nWeekDay TINYINT,
    			@dtRecDeb DATETIME,
    			@dtRecFin DATETIME
     
    	-- Si la date de début de la recherche n'est pas le 1er jour de la semaine,
    	-- on va rechercher tous les jours de la semaine contenant le jour de date de début et qui sont avant le jour de début ...
    	SELECT @nWeekDay = DATEPART(weekday, @_dtDateDebut)
     
    --	IF @nWeekDay <> @@DATEFIRST
    --	BEGIN
    --		SET @dtRecDeb = DATEADD(day, -@nWeekDay + 1, @_dtDateDebut)
    --
    --		WHILE @dtRecDeb < @_dtDateDebut
    --		BEGIN
    --			INSERT INTO @Tb VALUES (@dtRecDeb, DATEPART(dayofyear, @dtRecDeb)/7 + 1)
    --			SET @dtRecDeb = DATEADD(day, 1, @dtRecDeb)
    --		END
    --	END
     
    	-- Entre-temps, ajout des dates entre les dates de début et de fin ...
    	WHILE @_dtDateDebut <= @_dtDateFin
    	BEGIN
    		INSERT INTO @Tb VALUES (@_dtDateDebut, DATEPART(dayofyear, @_dtDateDebut)/7 + 1)
    		SET @_dtDateDebut = DATEADD(day, 1, @_dtDateDebut)
    	END
     
    	-- ... et idem pour la date de fin
    --	SELECT @nWeekDay = DATEPART(weekday, @_dtDateFin)
    --	IF @nWeekDay <> @@DATEFIRST + 6
    --	BEGIN
    --		SET @dtRecFin = DATEADD(day, 7 - @nWeekDay, @_dtDateFin)
    --		SET @_dtDateFin	= DATEADD(day, 1, @_dtDateFin)
    --
    --		WHILE @_dtDateFin <= @dtRecFin
    --		BEGIN
    --			INSERT INTO @Tb VALUES (@_dtDateFin,DATEPART(dayofyear, @_dtDateFin)/7 + 1)
    --			SET @_dtDateFin = DATEADD(day, 1, @_dtDateFin)
    --		END
    --	END
     
    	SELECT T.dtJour,
    			V.szArticle,
    			V.nVentes / 7
    	FROM @Tb T
    	JOIN dbo.TbVentes V ON DATEPART(dayofyear, V.szWeek)/7 + 1 = T.nSemaine
    	ORDER BY  T.dtJour, V.szArticle
    END
    Vous pouvez dé-commenter si vous le souhaitez passer des dates qui ne sont pas des débuts de semaine, pour récupérer des semaines complètes.

    Faites attention à la signification du résultat de votre requête, car avoir vendu 14 articles en une semaine ne signifie pas forcément que l'on a vendu 2 articles par jour toute la semaine ...

  3. #3
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Bonjour,

    Celle-ci est mieux : elle n'utilise pas de table temporaire :

    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
    ALTER PROCEDURE [dbo].[spTOTO]
    	@_dtDateDebut DATETIME,
    	@_dtDateFin DATETIME
    AS
    BEGIN
    	SET NOCOUNT ON
     
    	DECLARE @nWeekDay TINYINT,
    			@dtRecDeb DATETIME,
    			@dtRecFin DATETIME
     
    	-- Si la date de début de la recherche n'est pas le 1er jour de la semaine,
    	-- on va rechercher tous les jours de la semaine contenant le jour de date de début et qui sont avant le jour de début ...
    	SELECT @nWeekDay = DATEPART(weekday, @_dtDateDebut) 
    	IF @nWeekDay <> @@DATEFIRST
    		SET @_dtDateDebut = DATEADD(day, -@nWeekDay + 1, @_dtDateDebut)
     
    	-- ... et idem pour la date de fin
    	SELECT @nWeekDay = DATEPART(weekday, @_dtDateFin)
    	IF @nWeekDay <> @@DATEFIRST + 6
    		SET @_dtDateFin = DATEADD(day, 7 - @nWeekDay, @_dtDateFin)
     
    	-- Liste des dates
    	;WITH DATES AS
    	(
    			SELECT @_dtDateDebut Date, 1 Indice
    		UNION ALL
    			SELECT @_dtDateDebut + Indice Date, Indice + 1 Indice
    			FROM DATES
    			WHERE Date < @_dtDateFin
    	)
    	SELECT D.Date,
    			V.Article,
    			V.Ventes / 7 Ventes
    	FROM DATES D
    	JOIN dbo.TbVentes V ON DATEPART(dayofyear, V.Semaine)/7 + 1 = DATEPART(dayofyear, D.Date)/7 + 1
    	ORDER BY  D.Date, V.Article
    END
    A+

  4. #4
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    365
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 365
    Par défaut
    Merci elsuket pour tes réponses.. j'apprécie..

    En fait j'ai du passer par un script python pour faire cette tâche vu l'urgence..

    Je viens d'essayer ton code.

    Je ne comprends pas la partie
    Si la date de début de la recherche n'est pas le 1er jour de la semaine ..
    J'ai juste besoin d'ajouter les 7 jours automatiquement sans aucune vérification alors que ta proc stoc me génére 4 enregistrements et non 7 ..

    De plus, j'ai du passer par une conversion de dates pour que ça marche..

  5. #5
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Bonsoir,

    En fait j'ai pensé que comme vous deviez diviser le nombre de ventes par 7, il vous fallait donc 7 jours dans la semaine.

    Si vous passez donc une date de début et de fin qui soient, par exemple, tous deux des mercredi, je vais rechercher les :

    - Lundi et mardi précédent la date de début,
    - Jeudi, vendredi, samedi, dimanche suivant la date de fin

    Ce qui permet d'avoir des divisions "propres".

    J'ai juste besoin d'ajouter les 7 jours automatiquement sans aucune vérification alors que ta proc stoc me génére 4 enregistrements et non 7 ..

    De plus, j'ai du passer par une conversion de dates pour que ça marche..
    Pour me recréer ton cas d'utilisation sur mon PC, je me suis fait une table TbVentes dont voici la description :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE dbo.TbVentes
    (
    	Semaine CHAR(8) NULL,
    	Article VARCHAR(16)NULL,
    	Ventes TINYINT NULL
    )
    Avec le jeu de données suivant :

    Semaine Article Ventes
    20050101 article1 14
    20050101 article2 28
    20050108 article1 14
    20050108 article2 14


    Lorsque j'exécute :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXEC dbo.spTOTO '20050101', '20050108'
    J'obtiens :

    Date Article Ventes
    2005-01-01 00:00:00.000 article1 2
    2005-01-01 00:00:00.000 article2 4
    2005-01-02 00:00:00.000 article1 2
    2005-01-02 00:00:00.000 article2 4
    2005-01-03 00:00:00.000 article1 2
    2005-01-03 00:00:00.000 article2 4
    2005-01-04 00:00:00.000 article1 2
    2005-01-04 00:00:00.000 article2 4
    2005-01-05 00:00:00.000 article1 2
    2005-01-05 00:00:00.000 article2 4
    2005-01-06 00:00:00.000 article1 2
    2005-01-06 00:00:00.000 article2 4
    2005-01-07 00:00:00.000 article1 2
    2005-01-07 00:00:00.000 article2 2
    2005-01-08 00:00:00.000 article1 2
    2005-01-08 00:00:00.000 article2 2
    2005-01-09 00:00:00.000 article1 2
    2005-01-09 00:00:00.000 article2 2


    Qu'est-ce qu'il te fallait exactement ?

    A+

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 001
    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 : 22 001
    Billets dans le blog
    6
    Par défaut
    Il est beaucoup plus simple et incommensurablement plus performant d'utiliser une seule et simple requête SQL...

    Partant de votre table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE VENTES (WEEK DATETIME, ARTICLE VARCHAR(32), VENTES INT)
     
    INSERT INTO  VENTES VALUES ('20050101', 'article1', 14)
    INSERT INTO  VENTES VALUES ('20050101', 'article2', 28)
    INSERT INTO  VENTES VALUES ('20050108', 'article1', 14)
    INSERT INTO  VENTES VALUES ('20050108', 'article2', 28)
    Et utilisons une table de nombre qui devrait être présente dans toutes les bases de données de production, comme celle-ci :
    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 TABLE T_NUM (N INT NOT NULL PRIMARY KEY)
     
    INSERT INTO T_NUM VALUES (0)
    INSERT INTO T_NUM VALUES (1)
    INSERT INTO T_NUM VALUES (2)
    INSERT INTO T_NUM VALUES (3)
    INSERT INTO T_NUM VALUES (4)
    INSERT INTO T_NUM VALUES (5)
    INSERT INTO T_NUM VALUES (6)
    INSERT INTO T_NUM VALUES (7)
    INSERT INTO T_NUM VALUES (8)
    INSERT INTO T_NUM VALUES (9)
    ...
    INSERT INTO T_NUM VALUES (9999)
    Alors la requête devient triviale !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT DATEADD(d, N, WEEK) AS DATE_ART, ARTICLE, VENTES / 7 AS VENTE_JOUR
    FROM   VENTES AS V
           CROSS JOIN T_NUM 
    WHERE  N BETWEEN 0 AND 6
    ORDER  BY 2, 1

    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
    DATE_ART                                               ARTICLE                          VENTE_JOUR  
    ------------------------------------------------------ -------------------------------- ----------- 
    2005-01-01 00:00:00.000                                article1                         2
    2005-01-02 00:00:00.000                                article1                         2
    2005-01-03 00:00:00.000                                article1                         2
    2005-01-04 00:00:00.000                                article1                         2
    2005-01-05 00:00:00.000                                article1                         2
    2005-01-06 00:00:00.000                                article1                         2
    2005-01-07 00:00:00.000                                article1                         2
    2005-01-08 00:00:00.000                                article1                         2
    2005-01-09 00:00:00.000                                article1                         2
    2005-01-10 00:00:00.000                                article1                         2
    2005-01-11 00:00:00.000                                article1                         2
    2005-01-12 00:00:00.000                                article1                         2
    2005-01-13 00:00:00.000                                article1                         2
    2005-01-14 00:00:00.000                                article1                         2
    2005-01-01 00:00:00.000                                article2                         4
    2005-01-02 00:00:00.000                                article2                         4
    2005-01-03 00:00:00.000                                article2                         4
    2005-01-04 00:00:00.000                                article2                         4
    2005-01-05 00:00:00.000                                article2                         4
    2005-01-06 00:00:00.000                                article2                         4
    2005-01-07 00:00:00.000                                article2                         4
    2005-01-08 00:00:00.000                                article2                         4
    2005-01-09 00:00:00.000                                article2                         4
    2005-01-10 00:00:00.000                                article2                         4
    2005-01-11 00:00:00.000                                article2                         4
    2005-01-12 00:00:00.000                                article2                         4
    2005-01-13 00:00:00.000                                article2                         4
    2005-01-14 00:00:00.000                                article2                         4
    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/ * * * * *

Discussions similaires

  1. Réponses: 1
    Dernier message: 27/09/2012, 16h52
  2. Remplir une table de dimension
    Par gentelmand dans le forum Conception/Modélisation
    Réponses: 3
    Dernier message: 09/04/2009, 19h10
  3. Transférer des données d'une table à une autre
    Par picoloto dans le forum Langage SQL
    Réponses: 8
    Dernier message: 20/12/2005, 10h01
  4. Alimentation d'une table de dimension date
    Par kluh dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 01/07/2005, 14h34

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