Heim >Datenbank >MySQL-Tutorial >Wie subtrahiere ich einen erschöpfenden Wert von mehreren Zeilen und behalte gleichzeitig die kumulativen Werte bei?
Subtrahieren eines sich erschöpfenden Wertes von mehreren Losen
Bei diesem Problem geht es darum, eine erschöpfte Ressource (QuantityConsumed) auf mehrere Lagerbestände (Pooled_Lots) zu verteilen und gleichzeitig die kumulierten Mengen, die verbleibende Nachfrage und etwaige Überschüsse oder Defizite zu verfolgen.
Datenstrukturen:
Wir haben zwei Tische:
Gewünschtes Ergebnis:
Die Abfrage sollte für jedes Los in Pooled_Lots
einen Ergebnissatz generieren, einschließlich:
Pool
, Lot
, Quantity
, QuantityConsumed
, RunningQuantity
, RemainingDemand
, SurplusOrDeficit
.Lösungsansatz:
Ein rekursiver Common Table Expression (CTE) bietet eine effektive Lösung. Die Logik ist wie folgt:
RunningQuantity
durch Subtrahieren von QuantityConsumed
, wenn das Los Quantity
das verbleibende QuantityConsumed
überschreitet.RemainingDemand
als Differenz zwischen QuantityConsumed
und der Summe von RunningQuantity
und Quantity
des aktuellen Loses.SurplusOrDeficit
als Differenz zwischen RunningQuantity
und RemainingDemand
.SQL-Abfrage (anschaulich):
Die bereitgestellte Abfrage ist unvollständig und enthält einige logische Inkonsistenzen. Eine robuste Lösung erfordert eine sorgfältige Behandlung von Randfällen (z. B. wenn QuantityConsumed
Null ist oder die Gesamtmenge aller Lose in einem Pool überschreitet). Eine korrigierte und effizientere Abfrage müsste auf der Grundlage eines bestimmten Datenbanksystems (z. B. SQL Server, PostgreSQL, MySQL) erstellt werden. Das Folgende ist ein konzeptioneller Überblick über einen genaueren Ansatz:
<code class="language-sql">WITH RecursiveCTE AS ( -- Anchor member: Select the first lot for each pool SELECT PL.Pool, PL.Lot, PL.Quantity, PC.QuantityConsumed, PL.Quantity AS RunningQuantity, CASE WHEN PC.QuantityConsumed IS NULL THEN PL.Quantity ELSE PC.QuantityConsumed - PL.Quantity END AS RemainingDemand, 0 AS SurplusOrDeficit, ROW_NUMBER() OVER (PARTITION BY PL.Pool ORDER BY PL.Lot) as rn FROM Pooled_Lots PL LEFT JOIN Pool_Consumption PC ON PL.Pool = PC.PoolId WHERE PL.Lot = 1 --First lot UNION ALL -- Recursive member: Process subsequent lots SELECT PL.Pool, PL.Lot, PL.Quantity, PC.QuantityConsumed, CASE WHEN r.RemainingDemand > PL.Quantity THEN r.RunningQuantity - PL.Quantity ELSE r.RunningQuantity - r.RemainingDemand END AS RunningQuantity, CASE WHEN r.RemainingDemand > PL.Quantity THEN r.RemainingDemand - PL.Quantity ELSE 0 END AS RemainingDemand, CASE WHEN r.rn = (SELECT MAX(rn) FROM RecursiveCTE WHERE Pool = PL.Pool) THEN r.RunningQuantity - r.RemainingDemand ELSE 0 END AS SurplusOrDeficit, r.rn + 1 FROM Pooled_Lots PL INNER JOIN RecursiveCTE r ON PL.Pool = r.Pool AND PL.Lot = r.rn + 1 LEFT JOIN Pool_Consumption PC ON PL.Pool = PC.PoolId ) SELECT * FROM RecursiveCTE ORDER BY Pool, Lot;</code>
Ergebnisse:
In der Ausgabe werden die Details zu jedem Los angezeigt, einschließlich des kumulierten RunningQuantity
, des verbleibenden RemainingDemand
und aller SurplusOrDeficit
nach der Zuteilung. Die Genauigkeit der RunningQuantity
-, RemainingDemand
- und SurplusOrDeficit
-Berechnungen hängt von der genauen Logik ab, die im rekursiven CTE implementiert ist, um alle möglichen Szenarien zu bewältigen. Eine vollständige und getestete Lösung würde die Kenntnis des spezifischen Datenbanksystems und möglicherweise Beispieldaten zur Validierung erfordern.
Das obige ist der detaillierte Inhalt vonWie subtrahiere ich einen erschöpfenden Wert von mehreren Zeilen und behalte gleichzeitig die kumulativen Werte bei?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!