2012-02-23 13 views
5

Mam sytuację, w której muszę pobrać "ilość skonsumowaną" z jednej tabeli i zastosować ją do drugiej tabeli, która ma 1 lub więcej wierszy, które są "połączonymi partiami" o ilościach . Nie jestem pewien, jak opisać to lepiej, oto co mi chodzi z perspektywy tabeli:SQL - Odejmowanie wartości zubożających z wierszy

Table Pooled_Lots 
---------------------------- 
Id Pool Lot Quantity 
1 1  1 5 
2 1  2 10 
3 1  3 4 
4 2  1 7 
5 3  1 1 
6 3  2 5 

Table Pool_Consumption 
---------------------------- 
Id PoolId QuantityConsumed 
1 1  17 
2 2  8 
3 3  10 

muszę wynikowy zestaw wierszy z zapytania SQL, która będzie wyglądać następująco:

Pool Lot Quantity QuantityConsumed RunningQuantity RemainingDemand SurplusOrDeficit 
1  1 5   17     0    12    NULL 
1  2 10   17     0    2    NULL 
1  3 4   17     2    0    2 
2  1 7   8     0    1    -1 
3  1 1   10     0    9    NULL 
3  2 5   10     0    4    -4 

So, Pool_Consumption.QuantityConsumed musi być "wartością zubażania" odjętym od wierszy od Pooled_Lots, gdzie Pool_Consumption.PoolId = Pooled_Lots.Pool. Nie mogę dowiedzieć się, jak można stwierdzić, kwerendy, która mówi:

  • Jeśli nie w ostatnim rzędzie, AmtConsumedFromLot = Ilość - QuantityConsumed jeśli QuantityConsumed < ilość, inny Ilość
  • W przypadku większej liczby wierszy, QuantityConsumed = QuantityConsumed - Ilość
  • pętli aż do ostatniego wiersza
  • czy ostatnia rzędu, AmtConsumedFromLot = QuantityConsumed

Załóżmy id jest kluczem głównym, a cel DB SQL 2 005.

Edycja: Ponieważ ludzie są głoszenia jestem „nie daje wystarczających informacji, proszę zamknąć ten” Tu jest więcej: Jest NO zestaw dużo, że Pool_Consumption czerpie, musi wyciągnąć z wszystkich partii gdzie Pool_Consumption.PoolId = Pooled_Lots.Pool, dopóki QuantityConsumed nie zostanie całkowicie wyczerpane lub odejmuję od ostatniego podzbioru Pooled_Lots, gdzie Pool_Consumption.PoolId = Pooled_Lots.Pool

Nie wiem, jak to wyjaśnić. To nie jest zadanie domowe, to nie jest wymyślone "ćwiczenie myślowe". Potrzebuję pomocy, aby dowiedzieć się, jak poprawnie odjąć QuantityConsumed przeciwko wielu wierszy!

+1

Nie wiem, dlaczego ludzie są do prawa głosu na to pytanie, masz jakieś poważne problemy granulacji w danych. Tabela 'Pool_Consumption' nie określa, z której części pochodzą zużyte jednostki. Naprawiłem też literówkę. -1 – JohnB

+0

Nieważne, nie zamierzam zawracać sobie głowy twoimi literami. Przynajmniej poświęć trochę więcej czasu na uzyskanie danych na temat tego pytania! Jednak twój projekt jest wadliwy na samym początku. (głosowałam nad zamknięciem) – JohnB

+1

@JohnB To jest właśnie to, z czym obecnie się stykam, upraszczam tyle, ile mogę i bez ujawniania poufnych danych z mojej pracy.Zamiast być aroganckim i głoszącym, że zadaję głupie pytanie, niegodne głosów, być może możesz mnie oświecić, gdzie muszę dodać "ziarnistość", aby dojść do punktu, w którym mogę łatwiej uzyskać pożądaną produkcję? – Irinotecan

Odpowiedz

7

pozostawiamy jako ćwiczenie dla OP: Zastanawianie się poprawne wyniki podano przykładowych danych i podsumowujące wyniki następujące zapytanie:

-- Create some test data. 
declare @Pooled_Lots as table (Id int, Pool int, Lot int, Quantity int) 
insert into @Pooled_Lots (Id, Pool, Lot, Quantity) values 
    (1, 1, 1, 5), (2, 1, 2, 10), (3, 1, 3, 4), 
    (4, 2, 1, 7), 
    (5, 3, 1, 1), (6, 3, 2, 5) 
declare @Pool_Consumption as table (Id int, Pool int, QuantityConsumed int) 
insert into @Pool_Consumption (Id, Pool, QuantityConsumed) values 
    (1, 1, 17), (2, 2, 8), (3, 3, 10) 

select * from @Pooled_Lots order by Pool, Lot 
select * from @Pool_Consumption order by Pool 

; with Amos as (
    -- Start with Lot 1 for each Pool. 
    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 
     end as RunningQuantity, 
    case 
     when PC.QuantityConsumed is NULL then 0 
     when PL.Quantity >= PC.QuantityConsumed then 0 
     when PL.Quantity < PC.QuantityConsumed then PC.QuantityConsumed - PL.Quantity 
     end as RemainingDemand 
    from @Pooled_Lots as PL left outer join 
     @Pool_Consumption as PC on PC.Pool = PL.Pool 
    where Lot = 1 
    union all 
    -- Add the next Lot for each Pool. 
    select PL.Pool, PL.Lot, PL.Quantity, CTE.QuantityConsumed, 
    case 
     when CTE.RunningQuantity + PL.Quantity >= CTE.RemainingDemand then CTE.RunningQuantity + PL.Quantity - CTE.RemainingDemand 
     when CTE.RunningQuantity + PL.Quantity < CTE.RemainingDemand then 0 
     end, 
    case 
     when CTE.RunningQuantity + PL.Quantity >= CTE.RemainingDemand then 0 
     when CTE.RunningQuantity + PL.Quantity < CTE.RemainingDemand then CTE.RemainingDemand - CTE.RunningQuantity - PL.Quantity 
     end 
    from Amos as CTE inner join 
     @Pooled_Lots as PL on PL.Pool = CTE.Pool and PL.Lot = CTE.Lot + 1 
) 
select *, 
    case 
    when Lot = (select max(Lot) from @Pooled_Lots where Pool = Amos.Pool) then RunningQuantity - RemainingDemand 
    else NULL end as SurplusOrDeficit 
    from Amos 
    order by Pool, Lot 
+0

Dziękuję! Dokładnie to, czego chcę, jeszcze więcej! (Chociaż myślę, że będę włączenie RunningQuantity i RemainingDemand, ponieważ są one przydatne) – Irinotecan

+2

+1 na zastanawianie się, jakie pytanie – CodeThug

+2

@TimLarson. - wyglądał jak typowy magazyn stock picking problemu muszę 13-gwiazdkowe podbicie Sneetches. Chwyć pierwsze pudło na wysadzanej gwiazdą półce Sneetch i sprawdź, czy jest wystarczająco dużo. Jeśli tak, to świetnie. Jeśli nie, złap następne pole. Kiedy spadniesz z końca półki, weź swoją farbę i szablon i zacznij szukać Sneetches bez gwiazd na thar. – HABO

1

(na podstawie wersji 4 pytania jak mój WiFi zszedł od dłuższego czasu)

(SELECT 
    Pool, 
    SUM(Quantity) as Pool_Quantity 
FROM 
    Pooled_Lots 
GROUP BY 
    Pool) as Pool_Quantity_Table 

teraz masz tabelę z Pool Ilość zwinięte w jedną wartość.

Teraz pełna zapytania:

SELECT 
    Pool_Consumption.PoolID as Pool, 
    Pool_Quantity_Table.Pool_Quantity as Quantity, 
    Pool_Consumption.QuantityConsumed as AmtConsumedFromLot, 
    (Pool_Quantity_Table.Pool_Quantity - Pool_Consumption.QuantityConsumed) as SurplusOrDefecit 
FROM 
    Pool_Consumption 
INNER JOIN 
    (SELECT 
    Pool, 
    SUM(Quantity) as Pool_Quantity 
    FROM 
    Pooled_Lots 
    GROUP BY 
    Pool) as Pool_Quantity_Table 
ON (Pool_Consumption.PoolID = Pool_Quantity_Table.Pool); 
+0

Dziękuję za poświęcenie czasu na odpowiedź, JohnB. Chociaż podzielenie wyników na części jest nieco bardziej przydatne w mojej obecnej sytuacji, ta odpowiedź pomaga mi również zrozumieć rozwiązanie mojego problemu. Przepraszam za niedokładności w mojej oryginalnej tabeli wyników końcowych, myślałem, że dwukrotnie to sprawdziłem i nie widziałem, dopóki nie wprowadziłeś poprawki. – Irinotecan

+0

Jesteś bardzo mile widziany. Cieszę się, że masz rozwiązanie swojego problemu! :) – JohnB

Powiązane problemy