Sql 如何在oracle中同时使用distinct和sum?

Sql 如何在oracle中同时使用distinct和sum?,sql,oracle,sum,distinct,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

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

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分组求和(不同价格),然后按总和(所有价格)分组

说明:

ID  price
----------
1   30
2   20
3   30
4   20
内部查询将为每个ID选择不同的价格

i、 e

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

最终结果:

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

说明:

ID  price
----------
1   30
2   20
3   30
4   20
内部查询将为每个ID选择不同的价格

i、 e

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

最终结果:

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

结果。

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

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的所有行的价格都相同。您需要在每次使用字段时进行检查,直到修复数据为止。

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

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的所有行的价格都相同。您需要在每次使用字段时检查价格,直到修复数据为止

按id分组的第一个和(不同价格),然后是和(所有价格)

查看您的期望输出,您似乎还需要最终总和(类似于汇总),但是,汇总在您的情况下不会直接起作用

如果您希望以发布所需输出的方式对输出进行格式化,即在最后一行合计中使用标题,则可以在SQL*Plus中设置页面大小

  • 使用“联合所有”
比如说,

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>
因此,在最后还有一行是价格的总和

  • 使用汇总
或者,您可以使用汇总获得如下所示的总和:

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>
按id分组的第一个和(不同价格),然后是和(所有价格)

查看您的期望输出,您似乎还需要最终总和(类似于汇总),但是,汇总在您的情况下不会直接起作用

如果您希望以发布所需输出的方式对输出进行格式化,即在最后一行合计中使用标题,则可以在SQL*Plus中设置页面大小

  • 使用“联合所有”
比如说,

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>
因此,在最后还有一行是价格的总和

  • 使用汇总
或者,您可以使用汇总获得如下所示的总和:

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>

首先执行DISTINCT,然后进行汇总

SELECT ID, SUM(price)        -- sum of the distinct prices
FROM
 (
   SELECT DISTINCT ID, price -- distinct prices per ID
   FROM tab
 ) dt
GROUP BY ROLLUP(ID)          -- two levels of aggregation, per ID and total sum

首先执行DISTINCT,然后进行汇总

SELECT ID, SUM(price)        -- sum of the distinct prices
FROM
 (
   SELECT DISTINCT ID, price -- distinct prices per ID
   FROM tab
 ) dt
GROUP BY ROLLUP(ID)          -- two levels of aggregation, per ID and total sum

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;
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
| ID | PRICE |
|----|-------|
|  1 |    30 |
|  2 |    20 |
|  3 |    30 |
|  4 |    20 |
| ID |   100 |
查询1

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;
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
| ID | PRICE |
|----|-------|
|  1 |    30 |
|  2 |    20 |
|  3 |    30 |
|  4 |    20 |
| ID |   100 |

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;
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
| ID | PRICE |
|----|-------|
|  1 |    30 |
|  2 |    20 |
|  3 |    30 |
|  4 |    20 |
| ID |   100 |

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;
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
| ID | PRICE |
|----|-------|
|  1 |    30 |
|  2 |    20 |
|  3 |    30 |
|  4 |    20 |
| ID |   100 |
查询1

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;
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
| ID | PRICE |
|----|-------|
|  1 |    30 |
|  2 |    20 |
|  3 |    30 |
|  4 |    20 |
| ID |   100 |

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;
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
| ID | PRICE |
|----|-------|
|  1 |    30 |
|  2 |    20 |
|  3 |    30 |
|  4 |    20 |
| ID |   100 |

为什么您会说“首先选择不同的价格”,然后使用group by来执行此操作?在子查询中使用distinct将使事情更加清楚@博奈斯特:我知道会的。我正在解释我的问题。我建议你修改你的答案。我不明白为什么,如果选择一种清晰、自我记录的做事方式,你会选择一种不那么清晰、容易被误解的方式@博内斯特:更新了我的答案,解释了一下。我想你没有领会我的意思。当您不进行任何聚合时,为什么要使用group by来执行distinct?为什么不直接使用distinct呢?例如,
从tablename中选择不同的id、价格
为什么要说“首先选择不同的价格”,然后使用group by来执行此操作?在子查询中使用distinct将使事情更加清楚@博奈斯特:我知道会的。我正在解释我的问题。我建议你修改你的答案。我不明白为什么,如果选择一种清晰、自我记录的做事方式,你会选择一种不那么清晰、容易被误解的方式@博内斯特:更新了我的答案,解释了一下。我想你没有领会我的意思。当您不进行任何聚合时,为什么要使用group by来执行distinct?为什么不直接使用distinct呢?例如,
从表名中选择不同的id、价格