SQL - вычитание истощающего значения из строк - PullRequest
5 голосов
/ 23 февраля 2012

У меня есть ситуация, когда мне нужно взять «израсходованное количество» из одной таблицы и применить его ко второй таблице, имеющей 1 или более строк, которые являются «объединенными партиями» количеств. Я не уверен, как это лучше описать, вот что я имею в виду с точки зрения таблицы:

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

Мне нужен результирующий набор строк из запроса SQL, который будет выглядеть следующим образом:

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

Итак, Pool_Consulation.QuantityConsumed должно быть «истощающим значением», вычитаемым из строк из Pooled_Lots, где Pool_Consump.PoolId = Pooled_Lots.Pool. Я не могу понять, как бы вы сформулировали запрос, который говорит:

  • Если не в последней строке, AmtConsumedFromLot = Количество - Количество продолжится, если Количество увеличено <Количество, иначе Количество </li>
  • Если больше строк, то КоличествоСообщено = КоличествоСообщено - Количество
  • Цикл до последнего ряда
  • Если последняя строка, AmtConsumedFromLot = КоличествоConsumed

Предположим, что Id является первичным ключом, а целевой БД - SQL 2005.

Редактировать: Так как люди заявляют, что я "не даю достаточно информации, пожалуйста, закройте это". Вот еще: есть НЕТ установленный лот, из которого извлекается Pool_Consumpment, он должен быть взят из все лотов, где Pool_Consump.PoolId = Pooled_Lots.Pool, до тех пор, пока не будет полностью истощен кол-во кол-ва кол-во или вычтено последнее подмножество строк Pooled_Lots, где Pool_Consump.PoolId = Pooled_Lots.Pool

Я не знаю, как ещё это объяснить. Это не вопрос домашнего задания, это не выдуманное «упражнение на мысль». Мне нужна помощь, чтобы выяснить, как правильно вычесть Количество из нескольких строк!

Ответы [ 2 ]

7 голосов
/ 24 февраля 2012

Оставлено в качестве упражнения для OP: вычисление правильных результатов с учетом данных выборки и обобщение результатов следующего запроса:

-- 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
1 голос
/ 24 февраля 2012

(на основании версии 4 вопроса, так как мой WiFi довольно долго отключался)

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

Теперь у вас есть таблица с количеством пулов, свернутым в одно значение.

Теперь полный запрос:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...