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 :

Stock d'un article présent dans plusieurs emplacements de stockage pendant des périodes


Sujet :

Développement SQL Server

  1. #1
    Membre régulier
    Inscrit en
    Février 2004
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 84
    Points : 90
    Points
    90
    Par défaut Stock d'un article présent dans plusieurs emplacements de stockage pendant des périodes
    Bonjour, alors voici mon problème :

    J'ai des articles pouvant être stockés dans plusieurs emplacements et les mouvements de stock faits des jours différents
    Dans l'exemple ci-dessous on a 3 emplacements avec des mouvements à des dates différentes:

    Nom : pbstock1.png
Affichages : 129
Taille : 8,7 Ko

    Pour stocker ça j'ai une table de mouvements de stock, chaque enregistrement contient l'id de l'article concerné, l'id de l'emplacement, la date du mouvement et la quantité dans l'emplacement à la date du mouvement.

    Ce que je voudrais c'est un requête me renvoyant des périodes avec début et fin et la quantité pendant la période c-a-d la ligne Total de l'image. Donc dire du 2 au 4 janvier stock 13, le 5 janvier stock 32 etc.

    Voici un jeu d'essai de la table des mouvements :

    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
     
    IF OBJECT_ID('tempdb..#mvt') IS NOT NULL DROP TABLE #mvt
    CREATE table #mvt(idmvt int identity, idemplacement int, CreeLe date, idarticle int default 1, qtestock int)
    delete from #mvt
     
    insert into #mvt(#mvt.idemplacement, #mvt.CreeLe, #mvt.qtestock) VALUES
    (1, '01/01/2023', 9)
    ,(1, '03/01/2023', 10)
    ,(1, '08/01/2023', 15)
    ,(1, '11/01/2023', 13)
    ,(1, '13/01/2023', 20)
     
    ,(2, '01/01/2023', 3)
    ,(2, '05/01/2023', 12)
    ,(2, '09/01/2023', 10)
    ,(2, '11/01/2023', 18)
     
    ,(3, '01/01/2023', 10)
    ,(3, '06/01/2023', 15)
    ,(3, '12/01/2023', 23)
    Merci si quelqu'un peut m'aider

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Votre image, son total et votre jeu de données disent trois choses différentes.

    Sur l'image, le 2 janvier quantité = 23 (10 + 3 +10)
    Le total et le texte indiquent 13.
    Dans le jeu de données, le 2 janvier c'est 22 (9 + 3 + 10).

  3. #3
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Mais sinon :
    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
    with cte_calendar (cal_day, stop) as
    (
    select min(CreeLe), max(CreeLe)
      from #mvt
     union all
    select dateadd(day, 1, cal_day)
         , stop
      from cte_calendar
     where cal_day < stop
    )
      ,  cte_mvt_period (idmvt, idemplacement, DateDeb, DateFin, qtestock) as
    (
    select idmvt, idemplacement, CreeLe
         , coalesce(dateadd(day, -1, lead(CreeLe) over(partition by idemplacement, idarticle order by CreeLe)), max(CreeLe) over())
         , qtestock
      from #mvt
    )
      ,  cte_sum_jour (cal_day, qtestock, grp) as
    (
      select cal.cal_day
           , sum(mvt.qtestock) as qtestock
           , row_number() over(                               order by cal.cal_day asc)
           - row_number() over(partition by sum(mvt.qtestock) order by cal.cal_day asc)
        from cte_calendar   as cal
        join cte_mvt_period as mvt  on mvt.DateDeb <= cal.cal_day
                                   and mvt.DateFin >= cal.cal_day
    group by cal.cal_day
    )
      select min(cal_day) as DateDeb
           , max(cal_day) as DateFin
           , qtestock
        from cte_sum_jour
    group by qtestock, grp
    order by DateDeb asc;
     
    DateDeb     DateFin     qtestock
    ----------  ----------  --------
    2023-01-01  2023-01-02        22
    2023-01-03  2023-01-04        23
    2023-01-05  2023-01-05        32
    2023-01-06  2023-01-07        37
    2023-01-08  2023-01-08        42
    2023-01-09  2023-01-10        40
    2023-01-11  2023-01-11        46
    2023-01-12  2023-01-12        54
    2023-01-13  2023-01-13        61
    Testé sur db<>fiddle.

  4. #4
    Membre régulier
    Inscrit en
    Février 2004
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 84
    Points : 90
    Points
    90
    Par défaut
    Merci Waldar, ton code fonctionne mais je dois travailler sur ma vraie table qui contient 700000 lignes et là :
    Msg*530, Niveau*16, État*1, Ligne*41
    L'instruction a été terminée. La récursivité maximale 100 a été épuisée avant la fin de l'instruction.

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Rajoutez la clause option (maxrecursion 0) quelque part (probablement à la fin de la requête).

  6. #6
    Membre régulier
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Mars 2016
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Mars 2016
    Messages : 58
    Points : 105
    Points
    105
    Par défaut
    Bonjour,

    J'ai essayé de répondre à la demande par curiosité et je propose cela :

    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
     
     
    ;WITH cte
         AS (SELECT 0 AS offset
             UNION ALL
             SELECT offset + 1
             FROM   cte
             WHERE  cte.offset < 19),
         calend
         AS (SELECT Cast(Dateadd(day, cte.offset, '2023-01-01') AS DATE) AS jour
             FROM   cte),
         tmp
         AS (SELECT *,
                    First_value(#mvt.qtestock)
                      OVER(
                        partition BY calend.jour, #mvt.idemplacement
                        ORDER BY #mvt.creele DESC) AS stockfinal,
                    Row_number()
                      OVER(
                        partition BY calend.jour, #mvt.idemplacement
                        ORDER BY #mvt.creele DESC) AS rang
             FROM   calend
                    FULL JOIN #mvt
                           ON #mvt.creele <= calend.jour
             WHERE  calend.jour IS NOT NULL),
         tmp2
         AS (SELECT jour                    AS datedebut,
                    Sum(stockfinal)         AS totalstock,
                    First_value(jour)
                      OVER (
                        partition BY Sum(stockfinal)
                        ORDER BY jour DESC) AS datefin,
                    Row_number()
                      OVER (
                        partition BY Sum(stockfinal)
                        ORDER BY jour )     AS rang
             FROM   tmp
             WHERE  rang = 1
             GROUP  BY jour)
    SELECT datedebut,
           datefin,
           totalstock
    FROM   tmp2
    WHERE  rang = 1
    ORDER  BY datedebut
    par contre, tu es sûr du résultat ? au 13/01 on devrait avoir 61 pour moi ?!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    datedebut	datefin	totalstock
    2023-01-01	2023-01-02	22
    2023-01-03	2023-01-04	23
    2023-01-05	2023-01-05	32
    2023-01-06	2023-01-07	37
    2023-01-08	2023-01-08	42
    2023-01-09	2023-01-10	40
    2023-01-11	2023-01-11	46
    2023-01-12	2023-01-12	54
    2023-01-13	2023-01-20	61

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    En effet il y avait une coquille, j'avais indiqué une date de fin = date de création pour la dernière ligne mais ce n'était pas une bonne idée. J'ai corrigé en indiquant la date maximale.

Discussions similaires

  1. appel d un fichier dans plusieurs emplacement d un autre fichier
    Par arasm dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 20/08/2009, 17h38
  2. [XL-2000] Comment faire pour vérifier qu'un fichier est bien présent dans un emplacement précis
    Par Avinetor dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 05/06/2009, 14h12
  3. Réponses: 2
    Dernier message: 04/04/2008, 09h48
  4. procedure stockée pour insertion dans plusieurs tables
    Par bigwal2007 dans le forum ASP.NET
    Réponses: 1
    Dernier message: 22/11/2007, 22h58

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