2017-04-07 5 views
2

Ich versuche eine manuelle Funktion zu automatisieren, um Inventar zukünftigen Sendungen zuzuordnen, um zu bestimmen, wann wir wieder Teile produzieren müssen. So in einem einfachen Beispiel:SQL-Abfrage zum Zuordnen von Lagerbeständen zu bevorstehenden Sendungen

das Beispiel zu reinigen, ein wenig nach oben:

Table ShipmentSchedule 

Part ShipmentNumber QtyNeeded  
1   1    30 
1   2    30 
1   3    30 
2   1    40 
2   2    40 

Table Inventory 

Part QtyInventory 
1   40 
2   50 

würde Ich mag eine Abfrage erhalten, die die folgende ausgibt. Es nimmt den Inventarbetrag für jedes Teil und verwendet das Inventar, um Sendungen zu erfüllen, bis das Inventar ausläuft.

Part Shipment Qty Need Inventory Used Qty to Produce 
    1  1   30   30    0 
    1  2   30   10    20 
    1  3   30   0    30 
    2  1   40   40    0 
    2  2   40   0    40 
+0

Sie Probe nicht klar ist .. wie Sie das gewünschte Ergebnis erhalten gezeigt ??? – scaisEdge

+1

Hier ist ein großartiger Ort um anzufangen. http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ –

Antwort

3

Hier ist eine Möglichkeit. Auch ich denke, dass die letzte Zeile in der erwarteten Ausgabe falsch basiert, Ihren Beispieldatensatz ...

declare @ShipmentSchedule table (Part int, ShipmentNumber int, QtyNeeded int) 
insert into @ShipmentSchedule 
values 
(1,1,30), 
(1,2,30), 
(1,3,30), 
(2,1,40), 
(2,2,40) 

declare @Inventory table (Part int, QtyInventory int) 
insert into @Inventory 
values 
(1,40), 
(2,50) 


--if you want the Quantity To Produce to keep incrementing (as a running total), so you only need to take the last one, then use this 
select 
    s.Part 
    ,s.ShipmentNumber 
    ,s.QtyNeeded 
    ,case 
     when i.QtyInventory - sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber) > 0 
      then QtyNeeded 
     when QtyNeeded + (i.QtyInventory - sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber)) > 0 
      then QtyNeeded + (i.QtyInventory - sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber)) 
     else 0 
    end as InventoryUsed 
    ,case 
      when i.QtyInventory - sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber) > 0 
       then 0 
      when i.QtyInventory - sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber) < 0 
       then (i.QtyInventory - (sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber))) * - 1 
    end as QtyToProduce 
from 
    @ShipmentSchedule s 
    inner join 
    @Inventory i on i.Part = s.Part 


--or if you want how many to produce per shipment... wrap you can use a cte 
;with cte as(
    select 
     s.Part 
     ,s.ShipmentNumber 
     ,s.QtyNeeded 
     ,case 
      when i.QtyInventory - sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber) > 0 
       then QtyNeeded 
      when QtyNeeded + (i.QtyInventory - sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber)) > 0 
       then QtyNeeded + (i.QtyInventory - sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber)) 
      else 0 
     end as InventoryUsed 
     ,case 
       when i.QtyInventory - sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber) > 0 
        then 0 
       when i.QtyInventory - sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber) < 0 
        then (i.QtyInventory - (sum(s.QtyNeeded) over (partition by s.Part order by s.Part, s.ShipmentNumber))) * - 1 
     end as QtyToProduce 
     ,row_number() over (partition by s.Part order by s.Part, s.ShipmentNumber) as RN 
    from 
     @ShipmentSchedule s 
     inner join 
     @Inventory i on i.Part = s.Part) 

select 
    c.Part 
    ,c.ShipmentNumber 
    ,c.QtyNeeded 
    ,c.InventoryUsed 
    ,ISNULL(c.QtyToProduce - lag(QtyToProduce) over (partition by Part order by Part, ShipmentNumber),0) as QtyToProduce 
    --,ISNULL(c.QtyToProduce - (select top 1 QtyToProduce from cte where c.RN -1 = RN and c.Part = Part order by rn desc),0) as QtyToProduce --use this version to avoid using LAG 
from  
    cte c 

ERGEBNISSE

/*Running Total*/ 

+------+----------------+-----------+---------------+--------------+ 
| Part | ShipmentNumber | QtyNeeded | InventoryUsed | QtyToProduce | 
+------+----------------+-----------+---------------+--------------+ 
| 1 |    1 |  30 |   30 |   0 | 
| 1 |    2 |  30 |   10 |   20 | 
| 1 |    3 |  30 |    0 |   50 | 
| 2 |    1 |  40 |   40 |   0 | 
| 2 |    2 |  40 |   10 |   30 | 
+------+----------------+-----------+---------------+--------------+ 


/*CTE for each shipment*/ 

+------+----------------+-----------+---------------+--------------+ 
| Part | ShipmentNumber | QtyNeeded | InventoryUsed | QtyToProduce | 
+------+----------------+-----------+---------------+--------------+ 
| 1 |    1 |  30 |   30 |   0 | 
| 1 |    2 |  30 |   10 |   20 | 
| 1 |    3 |  30 |    0 |   30 | 
| 2 |    1 |  40 |   40 |   0 | 
| 2 |    2 |  40 |   10 |   30 | 
+------+----------------+-----------+---------------+--------------+ 
+0

Danke, ich hatte gerade damit fertig und habe eine sehr ähnliche Lösung . Eine Frage: Ich konnte die QtyToProduce ohne Verwendung von Cte mit einem etwas anderen Fall erhalten: Case When (QtyInventory-RunTot) * -1> QtyNeeded Dann QtyNeeded Wenn (QtyInventory - RunTot) * -1> 0 dann (QtyInventory - RunTot) * -1 Else 0 Ende Wie ist der Vorteil von CTE? –

+0

Sieht so aus, als hätten Sie eine laufende Gesamtsäule erstellt - haben Sie das getan und Ihre Tabelle aktualisiert? – scsimon

+0

Ich verwendete 2 Abfragen, zuerst lief die laufende Summe und die zweite führte die Case-Anweisung –

Verwandte Themen