Rumah > pangkalan data > tutorial mysql > Bagaimana Mengendalikan Nilai Mengurangkan dalam Baris SQL Menggunakan CTE Rekursif?

Bagaimana Mengendalikan Nilai Mengurangkan dalam Baris SQL Menggunakan CTE Rekursif?

Linda Hamilton
Lepaskan: 2025-01-10 09:47:41
asal
451 orang telah melayarinya

How to Handle Depleting Values in SQL Rows Using Recursive CTEs?

SQL: Mengendalikan penurunan nilai dalam baris

Dalam SQL, apabila bekerja dengan berbilang baris data, penolakan nilai secara berperingkat daripada set baris boleh menjadi mencabar, terutamanya jika nilai yang dikurangkan menghabiskan nilai sumber. Begini cara untuk menyelesaikan masalah jenis ini:

Andaikan anda mempunyai dua jadual:

  • Pooled_Lots: Mengandungi maklumat inventori (Id, Pool, Lot, Kuantiti)
  • Pool_Consumption: Penggunaan storan (Id, PoolId, QuantityConsumed)

Anda memerlukan set hasil, menolak nilai QuantityConsumed ​​dari jadual Pooled_Lots, dengan mengambil kira peraturan berikut:

  • Untuk baris bukan terakhir, jika QuantityConsumed kurang daripada atau sama dengan Quantity, tolak QuantityConsumed daripada Quantity.
  • Untuk berbilang baris, tolak QuantityConsumed daripada Quantity.
  • Gelung sehingga baris terakhir.
  • Untuk baris terakhir, tolak baki Kuantiti Digunakan daripada Kuantiti.

Untuk mencapai ini, ungkapan jadual biasa rekursif (CTE) boleh digunakan:

<code class="language-sql">WITH Amos AS (
    -- 从每个Pool的Lot 1开始。
    SELECT
        PL.Pool,
        PL.Lot,
        PL.Quantity,
        PC.QuantityConsumed,
        CASE
            WHEN PC.QuantityConsumed IS NULL THEN PL.Quantity
            WHEN PL.Quantity >= PC.QuantityConsumed THEN PL.Quantity - PC.QuantityConsumed
            WHEN PL.Quantity = PC.QuantityConsumed THEN 0
            WHEN PL.Quantity < PC.QuantityConsumed THEN 0  --处理消耗量大于库存量的情况
            ELSE PL.Quantity
        END AS RunningQuantity,
        CASE
            WHEN PC.QuantityConsumed IS NULL THEN PL.Quantity
            ELSE PC.QuantityConsumed
        END AS RemainingDemand,
        CASE
            WHEN PL.Quantity >= PC.QuantityConsumed THEN 0
            ELSE PC.QuantityConsumed - PL.Quantity
        END AS SurplusOrDeficit
    FROM
        Pooled_Lots PL
    LEFT JOIN
        Pool_Consumption PC ON PL.Pool = PC.PoolId AND PL.Lot = 1  -- 关联到Lot 1
    UNION ALL
    SELECT
        a.Pool,
        a.Lot + 1,
        PL.Quantity,
        PC.QuantityConsumed,
        CASE
            WHEN a.RunningQuantity >= PC.QuantityConsumed THEN a.RunningQuantity - PC.QuantityConsumed
            WHEN a.RunningQuantity < PC.QuantityConsumed THEN 0
            ELSE a.RunningQuantity
        END AS RunningQuantity,
        CASE
            WHEN PC.QuantityConsumed IS NULL THEN 0
            ELSE PC.QuantityConsumed
        END AS RemainingDemand,
        CASE
            WHEN a.RunningQuantity >= PC.QuantityConsumed THEN 0
            ELSE PC.QuantityConsumed - a.RunningQuantity
        END AS SurplusOrDeficit
    FROM
        Amos a
    INNER JOIN
        Pooled_Lots PL ON a.Pool = PL.Pool AND a.Lot + 1 = PL.Lot
    LEFT JOIN
        Pool_Consumption PC ON PL.Pool = PC.PoolId AND PL.Lot = a.Lot + 1
)
SELECT * FROM Amos;</code>
Salin selepas log masuk

CTE ini secara berulang menolak nilai QuantityConsumed daripada baris Pooled_Lots sehingga ia mencapai baris terakhir. Ia mengira RunningQuantity, RemainingDemand dan SurplusOrDeficit mengikut peraturan yang ditetapkan.

Atas ialah kandungan terperinci Bagaimana Mengendalikan Nilai Mengurangkan dalam Baris SQL Menggunakan CTE Rekursif?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan