繁体   English   中英

如何改善我的SQL代码以获得正确的结果?

[英]How can I improve my SQL code for correct results?

好吧,我不确定解决此问题的最佳方法是什么。 但让我举一个例子。 我要在这里实现的是获取P2值,该值等于尝试按降序对P2值求和时的进位。.10到1。

我有一张大桌子:

Category_Id Brand_Id Carry P2_0  P2_1  P2_3 ... P2_10
9           54       59    12    3     17       .
7           6        102   4     0     3        .
9           71       54    20    1     0        .
9           75       98    34    4     0        .
7           10       140   59    5     4        .

这是我的代码的主要逻辑:

SELECT CategoryCode,Brand_Id, (CASE
    WHEN P2_10 > =  Carry Then 'Error' 
    WHEN P2_10 + P2_9 > =  Carry Then '10' 
    WHEN P2_10 + P2_9 + P2_8  > =  Carry Then '9' 
    WHEN P2_10 + P2_9 + P2_8 + P2_7  >=  Carry Then '8' 
    WHEN P2_10 + P2_9 + P2_8 + P2_7 + P2_6  >=  Carry Then '7'
    WHEN P2_10 + P2_9 + P2_8 + P2_7 + P2_6 + P2_5 > =  Carry Then '6' 
    WHEN P2_10 + P2_9 + P2_8 + P2_7 + P2_6 + P2_5 + P2_4 > =  Carry Then '5'
    WHEN P2_10 + P2_9 + P2_8 + P2_7 + P2_6 + P2_5 + P2_4 + P2_3 > =  Carry Then '4' 
    WHEN P2_10 + P2_9 + P2_8 + P2_7 + P2_6 + P2_5 + P2_4 + P2_3 + P2_2 > =  Carry Then '3'
    WHEN P2_10 + P2_9 + P2_8 + P2_7 + P2_6 + P2_5 + P2_4 + P2_3 + P2_2 + P2_1 > =  Carry Then '2'
    WHEN P2_10 + P2_9 + P2_8 + P2_7 + P2_6 + P2_5 + P2_4 + P2_3 + P2_2 + P2_1 + P2_0 > =  Carry Then '1'
    ELSE NULL END) As Threshold  from BQ_15

现在这里的问题是对于brand_id 6,如果进位为106,则

 P2_10(50) + P2_9(50) + P2_8(3) + P2_7(3) = Carry (106) gives the right result 

 but if  P2_10 + P2_9 + P2_8 + P2_7 > Carry it has to go back to previous result, if in the previous result the new P2 was '0' it has to back further. 

 so if P2_10(50) + P2_9(50) + P2_8(2) + P2_7(0) + P2_6(30) > Carry (106) then it should skip P2_7 (because it is zero) and go to P2_8 (desired result) but for my code it goes to P2_7.

我知道我没有包含任何会跳过'0'的内容,这就是我整个问题所在,这是我如何在SQL中迭代我的代码在两种情况下都可以工作并获得所需的结果。

提前致谢

使用交叉应用进行行范围计算。 我使用了4个p2_xx列,并根据需要进行扩展。

from (
     -- sample data
     values (9,54,106,  50,50,2,0,30)     
     ) hugeTable (Category_Id, Brand_Id, Carry, P2_10, P2_9, P2_8, P2_7, P2_6) 
cross apply (
    select Threshold = min(p2n)
    from (
        select p2n,
             s = sum(p2val) over(order by p2n desc)
        from (
             values
             (10, P2_10), (9, P2_9), (8, P2_8), (7, P2_7), (6, P2_6) 
        ) t(p2n, p2val)
        where p2val>0
    ) t
    where s <= Carry
) t      

我使用sum()over(),如果您使用的是2008或更早版本,

from (
     -- sample data
     values (9,54,106,  50,50,2,0,30)     
     ) hugeTable (Category_Id, Brand_Id, Carry, P2_10, P2_9, P2_8, P2_7, P2_6) 
cross apply (
    select Threshold = min(p2n)
    from (
        select p2n,
             s = (select sum(p2val)
                 from (
                      values
                      (10, P2_10), (9, P2_9), (8, P2_8), (7, P2_7), (6, P2_6)  
                 ) t2(p2n, p2val)
                 where t2.p2n>=t.p2n )
        from (
             values
             (10, P2_10), (9, P2_9), (8, P2_8), (7, P2_7), (6, P2_6)  
        ) t(p2n, p2val)
        where p2val>0
    ) t
    where s <= Carry
) t

我怀疑您使用cross appy会遇到与先前答案有关的任何问题。 如果您确实有并发症,或者想要坚持使用原始的case表达式,那么找到一个可行的表达式并不难,只是有些混乱。 以下是其中一种情况:

WHEN P2_10 + P2_9 + P2_8 + P2_7 >= Carry
THEN coalesce(
    nullif(sgn(P2_8)  *  8, 0),
    nullif(sgn(P2_9)  *  9, 0),
    nullif(sgn(P2_10) * 10, 0),
    -1
)

实际上,当您只需要嵌套case表达式时,这不必要地变得复杂。 也许那是您没有意识到的可能:

WHEN P2_10 + P2_9 + P2_8 + P2_7 >= Carry
THEN case when P2_8 > 0 then 8 when P2_9 > 0 then 9 when P2_10 > 0 then 10 else -1 end

您是否有从全零开始然后跳过进位阈值的序列: (0, 0, 0, 200) 0,0,0,200 (0, 0, 0, 200) 那永远不会超过进位的款项呢? 我不认为其他答案可以解决这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM