2

我有这些表:SQL服务器选择的映射查询

Tb1ID 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 

Tb2CodeID 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 

我想没有光标的查询。

UsedValue是直到的总和低于Tb2.Value

我问这个问题之前:Select SQL Mapping Query

下面的查询是没有光标查询,但我的数据是非常大的,下面的查询速度很慢。

;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 

我在寻找具有上述性能的查询。

在此先感谢

回答

0

如果我的理解是否正确,这应该做的工作。测试性能与您的性能相比,并使用这里设置的值,它使用了样本查询一半的时间。使用两倍多的数据,它将使用运行示例查询所需时间的1/3:rd。所以它肯定更有效率,但是多少取决于表中的整体数据,你需要测试一下。 (Get the fiddle example here)

SELECT T1.* 
    , CASE WHEN CA.SumValue < T2.Value THEN T1.Value 
     ELSE (T1.Value+T2.Value) - CA.SumValue 
     END AS UsedValue 
    , T2.* 
FROM Tb1 T1 
JOIN Tb2 T2 ON T2.CodeID = T1.CodeID 
CROSS APPLY (SELECT SUM(C1.Value) SumValue 
    FROM Tb1 C1 WHERE C1.CodeID = T1.CodeID AND C1.ID <= T1.ID) CA 
WHERE ((T1.Value+T2.Value) - CA.SumValue) > 0 
-- Probably a better way to do this, but the beef is above. 
AND T1.CodeID IN 
    (SELECT T2.CodeID 
    FROM Tb2 T2 
    JOIN (SELECT CodeID, SUM(VALUE) SumVal 
     FROM Tb1 
     GROUP BY CodeID) SRC 
    ON SRC.CodeID = T2.CodeID AND SRC.SumVal > T2.Value) 

的评论后,部分是什么,我持怀疑态度,这是确保只有那些记录,Tb1中的总和超过Tb2中的值进行处理是什么让。这不是最有效的方法。

否则它上面的部分应该工作正常。此外,如果要显示UsedValue为0的结果,由于前一行已达到总和= Tb2.Value,因此改为将下面的行更改为> = 0

WHERE ((T1.Value+T2.Value) - CA.SumValue) > 0 

编辑:哦,小提琴不显示所有属于该结果列。所以忽略这一点,并在SSMS中试用以获得完整的结果集。