[简单]oracle group by问题解决记录

本文通过具体示例解释了在SQL查询中使用GROUP BY时如何正确应用聚合函数SUM来确保统计数据的准确性。当数据存在重复时,直接使用GROUP BY而不进行聚合可能会导致统计结果错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       同事写了个SQL,发现group by之后总数不对,不用group by查询有26条数据,使用group by查询总数只有16条数据,同事写的sql类似如下

       

 select t.sec_id,t.type_t,t.prod_id,t.amt_num
 from tmp_t t
 group by t.sec_id,t.type_t,t.prod_id,t.amt_num
 order by t.sec_id,t.type_t,t.prod_id,t.amt_num

    看了之后跟同事说group by 之后,amt_num要使用sum,同事一直不相信,只好写个简单的例子,上例子

   

with tmp_t as(
 select '0' as sec_id,'10000001' as type_t,'80008510' as prod_id,1 as amt_num from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000002','80008510',1 from dual union all
 select '0','10000002','80008510',1 from dual) 

    如上所示,只有2条数据,其他的是重复的

   

  with tmp_t as(
 select '0' as sec_id,'10000001' as type_t,'80008510' as prod_id,1 as amt_num from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000002','80008510',1 from dual union all
 select '0','10000002','80008510',1 from dual)  
  select *
   from tmp_t t
  order by t.sec_id, t.type_t, t.prod_id, t.amt_num

   

   group by使用sum:

  

  with tmp_t as(
 select '0' as sec_id,'10000001' as type_t,'80008510' as prod_id,1 as amt_num from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000002','80008510',1 from dual union all
 select '0','10000002','80008510',1 from dual)  
  select t.sec_id,t.type_t,t.prod_id,sum(t.amt_num)
 from tmp_t t
 group by t.sec_id,t.type_t,t.prod_id,t.amt_num
 order by t.sec_id,t.type_t,t.prod_id,t.amt_num

   结果如下

   

    总数是正确的

 

    group by 不使用sum:

   

  with tmp_t as(
 select '0' as sec_id,'10000001' as type_t,'80008510' as prod_id,1 as amt_num from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000001','80008510',1 from dual union all
 select '0','10000002','80008510',1 from dual union all
 select '0','10000002','80008510',1 from dual)  
  select t.sec_id,t.type_t,t.prod_id,t.amt_num
 from tmp_t t
 group by t.sec_id,t.type_t,t.prod_id,t.amt_num
 order by t.sec_id,t.type_t,t.prod_id,t.amt_num

   结果如下,数量不对

   

 

     全文完。

  

 

   

### Oracle 中 `GROUP BY 1` 的使用方法和含义 在 Oracle 数据库中,`GROUP BY 1` 是一种简写方式,表示按照查询结果中的第一列进行分组。这种写法通常被称为“按列位置分组”,而不是按列名分组。这种方式在某些情况下可以提高编写 SQL 语句的效率,尤其是在查询中包含复杂的表达式或多个列时。 例如,考虑以下 SQL 查询语句: ```sql SELECT department_id, COUNT(*) AS employee_count FROM employees GROUP BY department_id; ``` 上述语句可以等价地写成: ```sql SELECT department_id, COUNT(*) AS employee_count FROM employees GROUP BY 1; ``` 在第二个查询中,`GROUP BY 1` 表示按照 `SELECT` 子句中的第一个列(即 `department_id`)进行分组。这种方式可以避免重复书写列名,尤其在列名较长或表达式较复杂时非常有用[^1]。 需要注意的是,虽然 `GROUP BY 1` 提供了便利,但在实际开发中应谨慎使用。这是因为如果 `SELECT` 子句中的列顺序发生变化,`GROUP BY` 子句的含义也会随之改变,可能导致逻辑错误。因此,在需要确保 SQL 语句可读性和维护性的场景下,建议优先使用列名进行分组。 此外,在涉及多个列的分组时,可以通过增加数字来表示不同的列位置。例如: ```sql SELECT department_id, job_id, COUNT(*) AS employee_count FROM employees GROUP BY 1, 2; ``` 上述语句表示按照 `department_id` 和 `job_id` 进行分组,分别对应 `SELECT` 子句中的第一列和第二列。 ### 性能影响 在性能方面,使用 `GROUP BY 1` 与使用列名进行分组并没有本质区别。Oracle 的 SQL 解析器会将列位置解析为对应的列名,因此在执行计划和性能表现上两者是等效的。然而,在涉及大量数据或复杂查询时,合理选择分组字段仍然是优化查询性能的关键因素之一[^2]。 ### 示例 以下是一个使用 `GROUP BY 1` 的示例查询: ```sql SELECT department_id, SUM(salary) AS total_salary FROM employees WHERE salary > 5000 GROUP BY 1 ORDER BY total_salary DESC; ``` 该查询首先通过 `WHERE` 子句筛选出工资大于 5000 的员工记录,然后按照 `department_id` 进行分组,并计算每个部门的总工资,最后按照总工资降序排列结果[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值