如何在oracle中使用distinct和sum两者?

时间:2015-06-16 10:04:45

标签: sql oracle sum distinct

例如,我的表包含以下数据:

ID    price    
-------------
 1     10      
 1     10 
 1     20     
 2     20      
 2     20      
 3     30
 3     30
 4     5
 4     5
 4     15

所以给出上面的例子,

ID    price    
-------------
 1     30          
 2     20           
 3     30
 4     20
-----------
ID     100

如何在oracle中编写查询?第一个总和(不同价格)组由id然后总和(所有价格)。

5 个答案:

答案 0 :(得分:3)

我会非常小心这样的数据结构。首先,检查所有id只有一个价格:

select id
from table t
group by id
having count(distinct price) > 1;

我认为最安全的方法是为每个id(比如最大值)提取特定价格,然后进行汇总:

select sum(price)
from (select id, max(price) as price
      from table t
      group by id
     ) t;

然后,修复您的数据,这样您就不会有重复的添加维度。应该有一个表,每个id和价格有一行(或者可能有重复,但由有效和结束日期控制)。

数据搞砸了;你不应该假设给定id的所有行的价格是相同的。每次使用字段时都需要检查,直到修复数据为止。

答案 1 :(得分:1)

  

第一个总和(不同价格)组由id然后总和(所有价格)

查看所需输出,您似乎还需要最终总和(类似于ROLLUP),但 ROLLUP 不会直接适用于您的情况。< / p>

如果您希望格式化输出的方式与发布所需输出的方式完全相同,即最后一行总和的标题,则可以在 SQL * Plus 中设置 PAGESIZE

  • 使用 UNION ALL

例如,

SQL> set pagesize 7
SQL> WITH DATA AS(
  2  SELECT ID, SUM(DISTINCT price) AS price
  3  FROM t
  4  GROUP BY id
  5  )
  6  SELECT to_char(ID) id, price FROM DATA
  7  UNION ALL
  8  SELECT 'ID' id, sum(price) FROM DATA
  9  ORDER BY ID
 10  /

ID       PRICE
--- ----------
1           30
2           20
3           30
4           20

ID       PRICE
--- ----------
ID         100

SQL>

所以,最后还有一行额外的行,其中总和价格。

  • 使用 ROLLUP

或者,您可以使用 ROLLUP 获取总和,如下所示:

SQL> set pagesize 7
SQL> WITH DATA AS
  2    ( SELECT ID, SUM(DISTINCT price) AS price FROM t GROUP BY id
  3    )
  4  SELECT ID, SUM(price) price
  5  FROM DATA
  6  GROUP BY ROLLUP(id);

        ID      PRICE
---------- ----------
         1         30
         2         20
         3         30
         4         20

        ID      PRICE
---------- ----------
                  100

SQL>

答案 2 :(得分:0)

SELECT ID,SUM(price) as price
FROM
(SELECT ID,price
 FROM TableName
 GROUP BY ID,price) as T
 GROUP BY ID

<强>解释

内部查询将为每个ID选择不同的价格。

即,

ID    price    
-------------     
 1     10 
 1     20     
 2     20      
 3     30
 4     5
 4     15

然后外部查询将为每个ID选择SUM这些价格。

最终结果:

ID  price
----------
1   30
2   20
3   30
4   20

结果为SQL Fiddle

答案 3 :(得分:0)

首先执行DISTINCT,然后执行ROLLUP

#adiv

答案 4 :(得分:0)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE MYTABLE ( ID, price ) AS
          SELECT 1, 10 FROM DUAL
UNION ALL SELECT 1, 10 FROM DUAL
UNION ALL SELECT 1, 20 FROM DUAL
UNION ALL SELECT 2, 20 FROM DUAL
UNION ALL SELECT 2, 20 FROM DUAL
UNION ALL SELECT 3, 30 FROM DUAL
UNION ALL SELECT 3, 30 FROM DUAL
UNION ALL SELECT 4,  5 FROM DUAL
UNION ALL SELECT 4,  5 FROM DUAL
UNION ALL SELECT 4, 15 FROM DUAL;

查询1

SELECT COALESCE( TO_CHAR(ID), 'ID' ) AS ID,
       SUM( PRICE ) AS PRICE
FROM   ( SELECT DISTINCT ID, PRICE FROM MYTABLE )
GROUP BY ROLLUP ( ID )
ORDER BY ID

<强> Results

| ID | PRICE |
|----|-------|
|  1 |    30 |
|  2 |    20 |
|  3 |    30 |
|  4 |    20 |
| ID |   100 |