2012-02-23 68 views
5

我有一种情况,需要从一个表中获取“消耗的数量”,并将其应用于第二个具有“批量”数量的一行或多行的表。我不知道如何更好地形容它,这是我从一个表的角度是指:SQL - 从行中减去耗尽值

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_Consumption.QuantityConsumed需要在Pooled_Lots的行中减去“耗尽值”,其中Pool_Consumption.PoolId = Pooled_Lots.Pool。我想不出你会怎么说出一个查询,说:

  • 如果不是在最后一排,AmtConsumedFromLot =数量 - QuantityConsumed如果QuantityConsumed <数量,否则数量
  • 如果更多的行,QuantityConsumed = QuantityConsumed - 产品数量
  • 循环直到最后一行
  • 如果最后一行,AmtConsumedFromLot = QuantityConsumed

假设Id是主键,和所述目标DB是SQL 2 005

编辑:既然人都宣称我是“不给足够的信息,请关闭这个”这里比较:有NO集很多的Pool_Consumption而来,它需要从所有大量吸取借鉴其中Pool_Consumption.PoolId = Pooled_Lots.Pool,直到QuantityConsumed要么完全耗尽或我对减去行Pooled_Lots的最后一个子集,其中Pool_Consumption.PoolId = Pooled_Lots.Pool

我不知道该怎么越解释这一点。这不是一个家庭作业问题,这不是一个虚构的“思考练习”。我需要帮助,试图找出如何正确减去QuantityConsumed对多行!

+1

我不知道为什么现在的人了投票权这个问题,你有一些严重的数据粒度的问题。 “Pool_Consumption”表不指定消耗单位的来源。另外,我修正了一个错字。 -1 – JohnB 2012-02-23 20:00:41

+0

没关系,我不打算去修复所有的拼写错误。至少,花更多的时间在这个问题上直接获取数据!但是,您的设计有缺陷。 (投票结束) – JohnB 2012-02-23 20:04:28

+1

@JohnB这是我目前所面临的问题,尽可能简化并且不会泄露我工作中的机密数据。与其骄傲地宣称我在问一个不值得投票的愚蠢问题,或许你可以启发我在哪里需要添加“粒度”以使我自己能够更容易地产生期望的输出? – Irinotecan 2012-02-23 20:05:48

回答

7

左作为一个练习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 
+0

谢谢!这正是我想要的,甚至更多!(尽管我想我会包含RunningQuantity和RemainingDemand,因为它们很有用) – Irinotecan 2012-02-23 20:54:45

+2

+1,用于确定问题的出处 – CodeThug 2012-02-23 21:08:49

+2

@TimLarson - 它看起来像一个典型的仓库选股问题,我需要13个星期天的Sneetches。抓住星盘式Sneetch搁架上的第一个盒子,看看是否够用。如果是这样,很好。如果没有,抓住下一个框。当你从架子上掉下来时,你会抓住你的油漆和模板,开始寻找没有星星的Sneetches。 – HABO 2012-02-23 21:16:08

1

(基于问题的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); 
+0

谢谢你花时间回答这个问题,JohnB。尽管在当前情况下将结果拆分为更多帮助,但此答案确实有助于我理解我的问题的解决方案。我对原始最终结果表中的不准确性表示歉意,我认为我已经仔细检查过,并且在您进行修改之前没有看到它。 – Irinotecan 2012-02-23 21:10:23

+0

非常欢迎。我很高兴你能解决你的问题! :) – JohnB 2012-02-23 21:52:11