8
votes

Requête compliquée

Je ne sais pas si ce qui suit peut être effectué à l'aide d'une simple instruction SELECT, mais j'ai deux tables (tronquées avec les données nécessaires au problème).

Article d'inventaire

  • ID int (primaire)
  • Quantité int

    stock - contient des modifications du stock de l'élément d'inventaire (historique des stocks)

    • ID int (primaire)
    • inventaire_Item_id int (clé étrangère)
    • Quantité int
    • créé DateTime

      la quantité en stock est le changement de stock, tandis que la quantité d'inventaire est la quantité actuelle de cet élément

      Tout dans la colonne retournera 0 xxx

      la question

      maintenant, quoi J'aimerais savoir: est-il possible de sélectionner toutes les dates de la table de stock où la quantité d'exécution de l'inventaire_Item devient jamais nulle à l'aide d'un SELECT?

      Je sais que cela peut être fait de manière programmatique par simplement Sélection de toutes les données de stock dans un élément et soustrayez la quantité de stock individuellement à partir de la quantité d'élément d'inventaire actuelle, qui obtiendra la quantité avant la modification du stock. Puis-je faire cela avec un SELECT?


1 commentaires

Y aura-t-il jamais plus d'un enregistrement pour une combinaison donnée d'inventaire_Item_id et créée?


5 Réponses :


5
votes

(mise à jour) en supposant qu'il n'y aura jamais plus d'un enregistrement pour une combinaison donnée d'inventaire_Item_id et créé, essayez:

SELECT i.id,
       s.created,
       i.quantity - COALESCE(SUM(s2.quantity),0) AS running
FROM inventory_item i
JOIN stock s ON s.inventory_item_id = i.id
LEFT JOIN stock s2 ON s2.inventory_item_id = i.id and s.created < s2.created
GROUP BY i.id, s.created
HAVING running=0


4 commentaires

Puisque I.Quanity est la dernière quantité, cela est incorrect. Je pense que vous devez modifier votre champ Exécuter sur somme (S2.Quantité) . Ensuite, cela retournera les résultats corrects pour toutes les dates d'actions, pas seulement les dernières.


@Tom: J'ai modifié la requête pour prendre en compte le point que vous avez soulevé. Il serait incorrect d'utiliser la somme du stock .Quanity seul comme total en cours d'exécution, car il est utilisé pour contenir changements en quantités détenues en stock - Sommation Nous combien de changements il y avait eu, mais pas ce que le niveau de stock était à l'époque.


J'avais supposé la somme du stock.Quité était le total de la course à pied parce qu'il a dit: "La quantité en stock est le changement de stock, tandis que la quantité d'élément d'inventaire est la quantité actuelle de cet élément tout dans la colonne d'exécution retournera 0 ". Peut-être que j'interprète ce faux? J'ai pensé que la première entrée de la table stock serait le stock de départ.


La façon dont vous avez fonctionné fonctionnerait s'il y a ou non une histoire complète des stocks. C'est donc probablement le moyen le plus sûr d'aller à moins que vous sachiez que vous avez une histoire complète.



2
votes

Le moyen le plus logique de le faire est avec une somme cumulative. Mais, MySQL ne supporte pas cela.

L'approche la plus claire, à mon avis, est d'utiliser une sous-requête corrélée pour obtenir la quantité courante. Ensuite, c'est une simple question d'un clause pour sélectionner où il est 0 : xxx


0 commentaires

2
votes

Ma prise sur elle:

select
    inventory_item_id `item`,
    created `when`
from
    (select 
         @total := CASE WHEN @curr <> inventory_item_id
                   THEN quantity
                   ELSE @total+quantity END as running_total,
         inventory_item_id,
         created,                   
         @curr := inventory_item_id
     from
         (select @total := 0) a
         (select @curr  := -1) b
         (select inventory_item_id, created, quantity from stock order by inventory_item_id, created asc) c
     ) running_total
where running_total.running_total = 0;


0 commentaires

2
votes

Je crois que c'est une approche simple de cela. XXX


0 commentaires

2
votes

J'avais une réponse similaire basée sur un total en cours d'exécution à signaler trouvé ici ...

Vous pouvez faire avec MySQL @variables, mais les données doivent être pré-interrogées et commandées par Les données d'activité ... puis définissez un drapeau sur chaque ligne qui provoque la négative et ne conserve que celles. Quelque chose comme xxx

de cette façon, pour chaque élément d'inventaire, il fonctionne en arrière par date créée (commande par le décroissant créé par ID). Ainsi, lorsque l'ID d'inventaire change, regardez le champ "Quantité" de la table d'inventaire pour démarrer le décompte de la mise en marche usée. Si le même identifiant que le dernier enregistrement traité, utilisez simplement l'équilibre exécutant et soustrayez la quantité de cette entrée de stock.


0 commentaires