代码使用百分比

时间:2017-07-14 06:47:34

标签: sql oracle

我有查询表(COLORS)

COLOR_ID | COLOR_NAME | USAGE
=========+============+======
1        | BLUE       |
2        | RED        |
3        | WHITE      |

和数据表

PROD_ID | COLOR_ID
========+=========
1012    | 1
2036    | 1
3645    | 2

我需要SQL来计算用于产品的颜色百分比并更新COLORS表

所以结果应该更新表颜色:

COLOR_ID | COLOR_NAME | USAGE
=========+============+======
1        | BLUE       | 66.67
2        | RED        | 33.33
3        | WHITE      |  0.00

这里的问题是颜色白色(如果没有白色产品)这个颜色必须用0.00更新!

3 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情:

UPDATE COLORS T1 SET (USAGE) = 
 (SELECT CALC FROM (SELECT T1.COLOR_ID, COALESCE(CALC,0) CALC
                    FROM (SELECT DISTINCT COLOR_ID FROM COLORS) T1
                    LEFT JOIN (SELECT DISTINCT COLOR_ID
                                    , COUNT(*) OVER (PARTITION BY COLOR_ID) / COUNT(*) OVER (PARTITION BY 1) CALC
                               FROM COLORS_DATA) T2 ON T1.COLOR_ID = T2.COLOR_ID
                               ) T3 WHERE T1.COLOR_ID=T3.COLOR_ID)
 WHERE EXISTS(SELECT 1 FROM (SELECT T1.COLOR_ID, COALESCE(CALC,0) CALC
                    FROM (SELECT DISTINCT COLOR_ID FROM COLORS) T1
                    LEFT JOIN (SELECT DISTINCT COLOR_ID
                                    , COUNT(*) OVER (PARTITION BY COLOR_ID) / COUNT(*) OVER (PARTITION BY 1) CALC
                               FROM COLORS_DATA) T2 ON T1.COLOR_ID = T2.COLOR_ID
                               ) T3 WHERE T1.COLOR_ID=T3.COLOR_ID)
 ;

不使用UPDATE进行查询:

SELECT T1.COLOR_ID, COALESCE(CALC,0) CALC
FROM 
(SELECT DISTINCT COLOR_ID FROM COLORS) T1
LEFT JOIN (SELECT DISTINCT COLOR_ID
                , COUNT(*) OVER (PARTITION BY COLOR_ID) / COUNT(*) OVER (PARTITION BY 1) CALC
           FROM COLORS_DATA) T2 ON T1.COLOR_ID = T2.COLOR_ID
;

答案 1 :(得分:0)

你的问题与引用的问题不同,值得自己关注。由于您只需执行UPDATE,因此您还可以执行匿名PL / SQL块。对于您提供的数据,etsa的解决方案需要64个一致的获取。对于相同的输入数据,这个只需要35个一致的获取。如果您有更多数据,您可以自动查看它们,以便在更现实的情况下查看哪一项需要的工作量更少。

declare
   countall number;
begin
select count(*) into countall from prod_colors;

update colors c set usage = (
  select (count(*) / countall) * 100
  from prod_colors pc
  where pc.color_id = c.color_id
);
end;

答案 2 :(得分:0)

您需要使用OUTER JOIN来计算每种颜色的产品。 RATIO_TO_REPORT()函数计算结果集中每种颜色的百分比:

SQL> with cte as (
  2     select c.color_id
  3                , c.color_name
  4                , count(p.product_id) as prod_cnt
  5     from colors c
  6              left outer join products p
  7                     on p.color_id = c.color_id
  8     group by c.color_id
  9                , c.color_name
 10  )
 11  select color_id
 12        , color_name
 13        , ratio_to_report(prod_cnt) over () as usage
 14  from cte
 15  order by color_id;

  COLOR_ID COLOR_NAME                        USAGE
---------- ---------------------------- ----------
         1 BLUE                         .666666667
         2 RED                          .333333333
         3 WHITE                                 0

SQL> 
  

"所以结果应该更新表COLORS"

非常糟糕的做法。每次修改PRODUCTS表时,都必须重新计算整个COLORS表的用法。当用户实际需要知道使用百分比时,维护此类可导出值的开销将远远超过运行查询的偶然成本。