【问题标题】:How to get correct result in sum in Oracle如何在 Oracle 中得到正确的总和结果
【发布时间】:2021-10-28 12:15:47
【问题描述】:

我正在使用子查询来计算别名的总和,但它似乎返回错误的结果

我的桌子:

itm_code          itm_name            PACKING_STYLE       TOTAL_QUANTITY

3211483       DEODORIZATION              1                      32
3211484       DEODORIZATION FILTER       1                      20
3211485       FILTER                     30                     30
3211486       FILTER-RO 8INCH(S)         30                     30

这是我的食谱:

1. Full box = Integer of(total qty/ packing style)

2. Spare_box: via spare_quantity
   spare_quantity = total_quantity - full_box * packing_style.
   If spare_quantity = 0 => spare_box = 0
   If spare_quantity  > 0 => spare_box = 1  

这是我的查询:

    SELECT 
         l48.itm_code itmcd
         , l48.itm_name itmname
         , l48.PACKING_STYLE
         , l48.TOTAL_QUANTITY             
         , FULLBOX
         , SPARE_BOX
                    
         , SUM(FULLBOX + SPARE_BOX) AS TOTALBOX 
      from 
         log0048d l48
         , ( SELECT 
                
                ROUND(SUM(l48.TOTAL_QUANTITY / l48.PACKING_STYLE)) AS FULLBOX
                , CASE WHEN ROUND(SUM(l48.TOTAL_QUANTITY - (l48.TOTAL_QUANTITY/l48.PACKING_STYLE) * l48.PACKING_STYLE)) =  0 THEN  0
                       WHEN ROUND(SUM(l48.TOTAL_QUANTITY - (l48.TOTAL_QUANTITY/l48.PACKING_STYLE) * l48.PACKING_STYLE)) >  0 THEN  1
                   END AS SPARE_BOX
            FROM log0048d l48 )
         
     where 1 = 1
       AND l48.reqst_no  = 'SMO21071900398'         
      GROUP BY 
    
        l48.itm_code
        , l48.itm_name
        , l48.reqst_no_itm   
        , l48.PACKING_STYLE
        , l48.TOTAL_QUANTITY             
        , FULLBOX
        , SPARE_BOX

然后我收到的错误是:

itm_code        itm_name      PACKING_STYLE  TOTAL_QUANTITY    FULLBOX    SPAREBOX    TOTALBOX

3211483     DEODORIZATION           1             32             58          0           58
3211484     DEODORIZATION FILTER    1             20             58          0           58
3211485     FILTER                  30            30             58          0           58
3211486     FILTER-RO 8INCH(S)      30            30             58          0           58

我预期的正确结果如下:

itm_code        itm_name      PACKING_STYLE  TOTAL_QUANTITY    FULLBOX    SPAREBOX    TOTALBOX

3211483     DEODORIZATION           1             32             32          0           32
3211484     DEODORIZATION FILTER    1             20             20          0           20
3211485     FILTER                  30            30             1           0           1
3211486     FILTER-RO 8INCH(S)      30            30             1           0           1

我怎样才能得到预期的正确结果?

【问题讨论】:

    标签: sql oracle oracle11g


    【解决方案1】:

    要么你的样本数据不完整,要么我没有得到你的要求,但是

    select 
      code, 
      name, 
      packing_style, 
      total_quantity, 
      floor(total_quantity / packing_style) as fullbox, 
      sign(total_quantity - floor(total_quantity / packing_style) * packing_style) as sparebox,
      floor(total_quantity / packing_style) + sign(total_quantity - floor(total_quantity / packing_style) * packing_style) as totalbox 
    from thetable
    

    应该做的工作。不需要分组(尤其不是几乎每一列结果,这样的分组有什么意义)

    当然,您可以使其更具可读性和可维护性,例如如下

    with 
    
    fbe(code, fullbox) as (
      select 
        code, 
        floor(total_quantity / packing_style) as fullbox
      from thetable
    ),
    
    sbe(code, sparebox) as (
      select
        t.code,
        sign(t.total_quantity - fbe.fullbox * t.packing_style) as sparebox
      from thetable t inner join fbe on t.code = fbe.code
    )
    
    select 
      t.code,
      t.name,
      t.packing_style,
      t.total_quantity,
      fbe.fullbox,
      sbe.sparebox,
      fbe.fullbox + sbe.sparebox as totalbox
    from thetable t 
      inner join fbe on t.code = fbe.code 
      inner join sbe on t.code = sbe.code
    
    

    您还可以通过取模运算获得sparebox 的值,即如果total_quantity/packing_style 的其余部分与0 不同,您需要一个备用箱,否则您不需要。即你也可以这样写查询:

    select 
      code, 
      name, 
      packing_style, 
      total_quantity, 
      floor(total_quantity / packing_style) as fullbox, 
      sign(mod(total_quantity / packing_style)) as sparebox,
      floor(total_quantity / packing_style) + sign(mod(total_quantity/ packing_style)) as totalbox 
    from thetable
    

    此外,totalbox 将始终是 fullbox(如果总数量是包装样式的倍数)或 fullbox + 1(否则),因此您可以进一步简化如下:

    select 
      code, 
      name, 
      packing_style, 
      total_quantity, 
      floor(total_quantity / packing_style) as fullbox, 
      sign(mod(total_quantity / packing_style)) as sparebox,
      ceil(total_quantity / packing_style) as totalbox 
    from thetable
    

    请参阅floorceilsignmod 的文档

    【讨论】:

    • 感谢@derpirscher:您的提前对我很有用,对不起,因为我没有足够的声誉来投票给您,非常感谢^^
    猜你喜欢
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多