2013-01-20 138 views
0

我使用SQL Server 2012,我有這些表:選擇SQL映射查詢

Tb1中ID Int, CodeID Int, Value Int

ID  CodeID Value 
---------------------- 
1  1   10 
2  1   14 
3  1   5 
4  1   25 
5  2   12 
6  2   17 
7  2   4 
8  2   10 
9  2   6 

Tb2的CodeID Int Value Int

CodeID Value 
--------------- 
1   25 
2   20 

我想要一個從Tb1獲取記錄的查詢SUM(Tb1.Value)< = Tb2.Value

對於上面記錄的例子的結果是:

Tb1.ID Tb1.CodeID Tb1.Value UsedValue  Tb2.Value 
-------------------------------------------------------- 
1   1   10   10   25 
2   1   14   14   25 
3   1   5   1    25 
5   2   12   12   20 
6   2   17   8    20 

我用光標得到上面的查詢。但我的查詢,性能低下執行。 我想要一個沒有光標的查詢。

編輯1 UsedValue是Tb1.Value,直到Tb1.Value的總和低於Tb2.Value。

回答

0

試試這個:

;WITH Subtotals 
AS 
(
    SELECT 
    T1.Id, T1.CodeId, SUM(T2.Value) SubTotal 
    FROM Tb1 T1 
    JOIN Tb1 T2 
     ON T1.CodeId = T2.CodeId 
     AND T1.Id >= T2.Id 
    GROUP BY T1.Id, T1.CodeId 
) 
SELECT 
    S.ID, 
    S.CodeID, 
    T1.Value, 
    CASE WHEN T2.value >= S.Subtotal 
     THEN T1.value 
     ELSE T1.value - (S.Subtotal - T2.value) 
    END UsedValue, 
    T2.Value T2Value 
FROM Subtotals S 
    JOIN Tb2 T2 
     ON S.CodeId = T2.CodeId 
    JOIN Tb1 T1 
     ON S.Id = T1.Id 
WHERE T2.Value >= S.SubTotal - T1.Value 

參見導致上SQL FIDDLE

0
select 
T.Id 
, T.CodeId 
, T.Value 
, T.Value -(Total - T2.Value) as UsedValue 
, T2.Value as T2_Value 
from 
(
    select a.id 
    , a.codeid 
    , a.Value 
    , sum(b.value) as Total 
    from Tb1 a join Tb1 b 
    on a.Id >= b.id and a.CodeId = b.CodeId 
    group by a.id, a.CodeId, a.Value 
) T 
join Tb2 T2 
on T.CodeId = T2.CodeId 
where Total < (T2.Value + T.Value) 

只有一個假設,當我寫了這個代碼。那些行按ID排序,如果不是這樣,你必須添加排序列!

0
select id,codeid,value,case when vt>0 then value else value+vt end usedvalue, 
     value2 
from (select *, value2-runtot vt, 
     max(case when value2-runtot<0 then value2-runtot else -runtot end) 
     over(PARTITION BY codeid) usedvalue 
      from (SELECT t1.id, t1.codeid, t1.value, t2.value value2, 
       sum(t1.value) OVER(PARTITION BY t1.codeid ORDER BY t1.id) runtot 
       FROM tb1 t1 
       INNER JOIN tb2 t2 ON t1.codeid = t2.codeid 
      ) X 
      )Y 
where vt>=usedvalue