Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在Oracle汇总中组合MAX和SUM_Sql_Oracle_Oracle12c - Fatal编程技术网

Sql 在Oracle汇总中组合MAX和SUM

Sql 在Oracle汇总中组合MAX和SUM,sql,oracle,oracle12c,Sql,Oracle,Oracle12c,以下是我的SQL: WITH source1 AS ( SELECT 'Fruit' foodtype, 'Apple' food, 20 weight FROM dual UNION SELECT 'Fruit' foodtype, 'Apple' food, 30 weight FROM dual UNION SELECT 'Fruit' foodtype, 'Grape' food, 1 weight FROM dual UNION SELECT 'Veg'

以下是我的SQL:

WITH source1 AS (
   SELECT 'Fruit' foodtype, 'Apple'  food, 20 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Apple'  food, 30 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Grape'  food, 1  weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Carrot' food, 40 weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Leek'   food, 20 weight FROM dual
)
SELECT grouping(food) lv, foodtype, food, max(weight) weight
FROM   source1
GROUP BY foodtype, ROLLUP (food);
输出如下所示:

LV FOODTYPE FOOD   WEIGHT
-- -------- ------ ------
0  Veg      Leek       20
0  Veg      Carrot     40
1  Veg                 40
0  Fruit    Apple      30
0  Fruit    Grape       1
1  Fruit               30
LV FOODTYPE FOOD   WEIGHT
-- -------- ------ ------
0  Veg      Leek       20
0  Veg      Carrot     40
1  Veg                 60
0  Fruit    Apple      30
0  Fruit    Grape       1
1  Fruit               31
WITH source1 AS (
   SELECT 'Fruit' foodtype, 'Apple'  food, 20 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Apple'  food, 30 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Grape'  food, 1  weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Carrot' food, 40 weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Leek'   food, 20 weight FROM dual
)
SELECT grouping(s.food) lv, s.foodtype, s.food,
       CASE WHEN grouping(s.food)=1 THEN
          sum(CASE WHEN grouping(s.food)=1 THEN 0 ELSE max(s.weight) END) OVER (PARTITION BY s.foodtype ORDER BY s.food)
       ELSE
          max(s.weight)
       END weight
FROM   source1 s
GROUP BY s.foodtype, ROLLUP (s.food)
我希望它看起来像这样:

LV FOODTYPE FOOD   WEIGHT
-- -------- ------ ------
0  Veg      Leek       20
0  Veg      Carrot     40
1  Veg                 40
0  Fruit    Apple      30
0  Fruit    Grape       1
1  Fruit               30
LV FOODTYPE FOOD   WEIGHT
-- -------- ------ ------
0  Veg      Leek       20
0  Veg      Carrot     40
1  Veg                 60
0  Fruit    Apple      30
0  Fruit    Grape       1
1  Fruit               31
WITH source1 AS (
   SELECT 'Fruit' foodtype, 'Apple'  food, 20 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Apple'  food, 30 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Grape'  food, 1  weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Carrot' food, 40 weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Leek'   food, 20 weight FROM dual
)
SELECT grouping(s.food) lv, s.foodtype, s.food,
       CASE WHEN grouping(s.food)=1 THEN
          sum(CASE WHEN grouping(s.food)=1 THEN 0 ELSE max(s.weight) END) OVER (PARTITION BY s.foodtype ORDER BY s.food)
       ELSE
          max(s.weight)
       END weight
FROM   source1 s
GROUP BY s.foodtype, ROLLUP (s.food)
换言之,我希望汇总结果是每种食物的最大重量的总和,而不是食物种类中所有最大重量的总和

我确实有一种解决方案,但这意味着必须添加一层额外的SQL语句嵌套:

WITH source1 AS (
   SELECT 'Fruit' foodtype, 'Apple'  food, 20 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Apple'  food, 30 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Grape'  food, 1  weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Carrot' food, 40 weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Leek'   food, 20 weight FROM dual
), source_grp AS (
   SELECT s.foodtype, s.food, max(s.weight) max_weight
   FROM   source1 s
   GROUP BY foodtype, food
)
SELECT grouping(g.food) lv, g.foodtype, g.food, sum(g.max_weight) weight
FROM   source_grp g
GROUP BY g.foodtype, ROLLUP (g.food);
有没有一种不需要额外嵌套的方法

当然,这个例子与我的实际情况相比大大简化了,这就是为什么我试图找到一种减少代码行数的方法。将SQL语句减少60行代码可以大大简化其长期维护。

您可以使用row\u number代替:


您可以将window函数与CASE Expression结合使用,以获得所需的结果:

您可以使用Union,因此总选择数仅为2

WITH source1 AS (
   SELECT 'Fruit' foodtype, 'Apple'  food, 20 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Apple'  food, 30 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Grape'  food, 1  weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Carrot' food, 40 weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Leek'   food, 20 weight FROM dual
)
SELECT foodtype, food, max(weight) weight
FROM   source1
GROUP BY foodtype, food
UNION
(SELECT DISTINCT FOODTYPE, NULL, SUM(WEIGHT) TOTAL_WEIGHT  FROM SOURCE1 GROUP BY FOODTYPE);

几天后再次访问此。可以这样做:

LV FOODTYPE FOOD   WEIGHT
-- -------- ------ ------
0  Veg      Leek       20
0  Veg      Carrot     40
1  Veg                 40
0  Fruit    Apple      30
0  Fruit    Grape       1
1  Fruit               30
LV FOODTYPE FOOD   WEIGHT
-- -------- ------ ------
0  Veg      Leek       20
0  Veg      Carrot     40
1  Veg                 60
0  Fruit    Apple      30
0  Fruit    Grape       1
1  Fruit               31
WITH source1 AS (
   SELECT 'Fruit' foodtype, 'Apple'  food, 20 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Apple'  food, 30 weight FROM dual UNION
   SELECT 'Fruit' foodtype, 'Grape'  food, 1  weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Carrot' food, 40 weight FROM dual UNION
   SELECT 'Veg'   foodtype, 'Leek'   food, 20 weight FROM dual
)
SELECT grouping(s.food) lv, s.foodtype, s.food,
       CASE WHEN grouping(s.food)=1 THEN
          sum(CASE WHEN grouping(s.food)=1 THEN 0 ELSE max(s.weight) END) OVER (PARTITION BY s.foodtype ORDER BY s.food)
       ELSE
          max(s.weight)
       END weight
FROM   source1 s
GROUP BY s.foodtype, ROLLUP (s.food)

老实说,我也不是100%肯定我喜欢这个答案。根据上下文和维护的角度来看,CASE-WHEN语句比多级SELECT语句更难理解。

很抱歉,它给出了错误的输出。我只从每种食物类型中获得第一种食物。@cartbeforehorse。您只需要修复partitionby子句。我更新了答案。即使你做了一点修改,你使用的SELECT语句数量也不会比我在问题中使用的更少。你只是用一种不同的方式来嵌套它们。当分解时,这实际上比我在问题中建议的答案更复杂。您已经将lv列添加到源表中,而实际上它根本不是源数据的一部分。要首先获得lv值,首先需要对源数据进行分组。所以事实上,你会得到4条SELECT语句,而不是我的3条,或者3条而不是2条,这取决于你如何计算。巧妙地使用了无界前置和1前置之间的行。@cartbeforehorse,我已经更新了我的答案,并提供了一个使用total select 2的替代解决方案。但这给出了错误的oputput。水果总数是51,而我预期是31。您仍然需要对源进行分组。