`
DangDang0701
  • 浏览: 76963 次
  • 性别: Icon_minigender_2
  • 来自: 大连
社区版块
存档分类
最新评论

group by 和 partition by的比较

阅读更多
今天看到一个老兄的问题,
大概如下:
查询出部门的最低工资的userid 号
表结构:

D号      工资      部门
userid  salary   dept
  1      2000      1
  2      1000      1
  3      500       2
  4      1000      2

有一个高人给出了一种答案:
SELECT MIN (salary) OVER (PARTITION BY dept ) salary, dept   
FROM ss

运行后得到:
1000 1
1000 1
500 2
500 2
楼主那位老兄一看觉得很高深。大叹真是高人阿~
我也觉得这位老兄实在是高啊。

但我仔细研究一下发现那位老兄对PARTITION BY的用法理解并不深刻。并没有解决楼主的问题。
大家请看我修改后的语句
SELECT userid,salary,dept,MIN (salary) OVER (PARTITION BY dept ) salary  
FROM ss

运行后的结果:
userid   salary  dept      MIN (salary) OVER (PARTITION BY dept ) 
1 2000 1 1000
2 1000 1 1000
3 500 2 500
4 1000 2 500

大家看出端倪了吧。
高深的未必适合。

一下是我给出的答案:
SELECT * FROM SS
INNER JOIN (SELECT MIN(SALARY) AS SALARY, DEPT FROM SS GROUP BY DEPT) SS2
USING(SALARY,DEPT)

运行后的结果:
salary  dept     userid
1000 1 2
500 2 3

由此我想到总结一下group by和partition by的用法
group by是对检索结果的保留行进行单纯分组,一般总爱和聚合函数一块用例如AVG(),COUNT(),max(),main()等一块用。

partition by虽然也具有分组功能,但同时也具有其他的功能。
它属于oracle的分析用函数。
借用一个勤快人的数据说明一下:

sum()   over   (PARTITION   BY   ...)   是一个分析函数。   他执行的效果跟普通的sum   ...group   by   ...不一样,它计算组中表达式的累积和,而不是简单的和。  
   
  表a,内容如下:  
  B C D  
  02 02 1  
  02 03 2  
  02 04 3  
  02 05 4  
  02 01 5  
  02 06 6  
  02 07 7  
  02 03 5  
  02 02 12  
  02 01 2  
  02 01 23  
   
  select   b,c,sum(d)   e   from   a   group   by   b,c  
  得到:  
  B C E  
  02 01 30  
  02 02 13  
  02 03 7  
  02 04 3  
  02 05 4  
  02 06 6  
  02 07 7  
   
  而使用分析函数得到的结果是:  
  SELECT   b,   c,   d,   SUM(d)   OVER(PARTITION   BY   b,c   ORDER   BY   d)   e   FROM   a  
  B C E  
  02 01 2  
  02 01 7  
  02 01 30  
  02 02 1  
  02 02 13  
  02 03 2  
  02 03 7  
  02 04 3  
  02 05 4  
  02 06 6  
  02 07 7  
  结果不一样,这样看还不是很清楚,我们把d的内容也显示出来就更清楚了:  
  SELECT   b,   c,   d,SUM(d)   OVER(PARTITION   BY   b,c   ORDER   BY   d)   e   FROM   a  
  B C D E  
  02 01 2 2                     d=2,sum(d)=2  
  02 01 5 7                     d=5,sum(d)=7  
  02 01 23 30                   d=23,sum(d)=30  
  02 02 1 1                     c值不同,重新累计  
  02 02 12 13  
  02 03 2 2  
  02 03 5 7  
  02 04 3 3  
  02 05 4 4  
  02 06 6 6  
  02 07 7 7
1
0
分享到:
评论

相关推荐

    详解partition by和group by对比

    在SQL查询中,`GROUP BY` 和 `PARTITION BY` 都是用来处理数据分组的,但它们在功能和使用场景上有所不同。首先,`GROUP BY` 是一个基础的分组函数,它根据指定的列将数据进行分组,并且通常与聚合函数如 `SUM`, `...

    SQLServer中Partition By及row_number 函数使用详解

    在SQL Server中,`PARTITION BY` 和 `ROW_NUMBER()` 是两种非常重要的分析函数,它们在处理大数据集时尤其有用。本文将详细讲解这两个函数的使用方法及其在实际场景中的应用。 `PARTITION BY` 关键字是分析函数的一...

    Group BY 的另一种写法

    这里的`OVER(PARTITION BY column1)`部分相当于`GROUP BY column1`,而`ORDER BY some_column`则确定了在每个组内如何选择记录。 在大数据量处理时,优化`GROUP BY`语句的写法至关重要,因为它直接影响到查询的效率...

    只满足某个条件的查询效率分析

    介绍了 1.NOT EXISTS, 2.GROUP BY ... [HAVING ...] 3.count(*) over(partition by ...) 做查询的效率,以及各自的使用方法

    My SQL group by取同组第一条

    在MySQL 8.0中,为了解决这个问题,你需要确保`ORDER BY`和`LIMIT`子句结合使用,因为`GROUP BY`不再保证按排序顺序返回结果。正确的查询可能是这样的: ```sql SELECT SwipeID, MemberID, AddTime FROM ( SELECT ...

    ch08_ 秋招秘籍 C1

    为了将结果转换为每场比赛日期对应胜和负的计数,我们可以使用SQL的CASE语句配合GROUP BY和COUNT函数。以下是转换的SQL语句: ```sql SELECT cdate, SUM(CASE WHEN result = '胜' THEN 1 ELSE 0 END) AS 胜, SUM...

    mysql分组取每组前几条记录(排名) 附group by与order by的研究

    这通常涉及到`GROUP BY`和`ORDER BY`子句的使用。本篇文章将深入探讨这两种SQL语句,并提供多种实现方式。 首先,`GROUP BY`子句用于将数据按照一个或多个列进行分组,它常与聚合函数(如`COUNT`, `SUM`, `AVG`, `...

    oracle函数介绍(5) 分析函数简述.doc

    第五篇 分析函数简述 分析函数的语法结构比较复杂,但多数函数都具有相同的语法...Partition没啥说的,功能强大参数少,主要用于分组,可以理解成select中的group by。不过它跟select语句后跟的group by 子句并不冲突。

    SQL中的开窗函数详解可代替聚合函数使用

    在这个例子中,`COUNT(FName) OVER(PARTITION BY FCity)`在每个城市内部计算了薪资低于5000的员工数量,而无需使用GROUP BY。 除了聚合开窗函数,还有排序开窗函数,它们的主要函数包括`ROW_NUMBER()`、`RANK()`、`...

    ORACLE去除重复数据方法

    - `ROW_NUMBER() OVER (PARTITION BY CONTRACTID ORDER BY ALTER_DATE) AS rn`:此行代码使用`ROW_NUMBER()`函数为每个`CONTRACTID`分组内的记录分配一个行号,按照`ALTER_DATE`升序排列。 2. **最终查询**: - ...

    oracle分组排序统计高级用法

    - `OVER`子句可以包括`PARTITION BY`、`ORDER BY`和`ROWS`或`RANGE`之间的范围。 **2. `ROW_NUMBER()`、`RANK()`、`DENSE_RANK()`的区别** - **`ROW_NUMBER()`**: 给每一行分配一个唯一的连续整数,无论是否有...

    分析函数,数据库开发

    RATIO_TO_REPORT(column_name) OVER (PARTITION BY partition_column ORDER BY order_column) ``` ##### 示例 假设有一个销售数据表,我们想计算每个产品的销售额在其所在类别的总销售额中的比例。 ```sql SELECT ...

    Hive经典面试实操sql题

    假设面试官会问到如何统计每个团队每年的交易数量,可以使用`GROUP BY`和`COUNT`: ```sql SELECT team, year, COUNT(*) as transaction_count FROM t1 GROUP BY team, year; ``` 3. **时间序列分析** 如果...

    sql 语句的笔试题

    SQL语句:select * from (select name, year b1, lead(year) over (partition by name order by year) b2, lead(m,2) over(partition by name order by year) b3,rank()over( partition by name order by year) rk ...

    oracle分析函数的使用

    分析函数的工作顺序位于`JOIN`、`WHERE`子句、`GROUP BY`和`HAVING`之后,但在主查询的`ORDER BY`子句之前。因此,分析函数只能出现在`SELECT`列表和主查询的`ORDER BY`子句中。 2. `ROW_NUMBER()`函数可以为每个...

    SQL中窗口函数的使用

    窗口函数在`GROUP BY`和`HAVING`之后,`SELECT`之前执行。在SQL语句的执行顺序中,它位于`FROM/JOIN`、`WHERE`、`GROUP BY`、`聚合函数`、`HAVING`之后,`SELECT`、`DISTINCT`、`UNION`等操作之前。 5. **...

    SQL精典试题 非常不错的

    SELECT *, RANK() OVER (PARTITION BY ID ORDER BY YAGE DESC) AS AgeRank FROM TEST_A ) SELECT * FROM MaxAgeRank WHERE AgeRank ; ``` 4. 检索出test_a表中的记录,其id在test_b表中出现过2次以上(含2次): ...

    oracle分析函数.doc

    这里,`COUNT(*) OVER (PARTITION BY corp ORDER BY year)`会根据年份递增的方式累计每个公司每年的电影数量。 ##### 4.3 RANK, DENSE_RANK, ROW_NUMBER 这三个函数用于对结果集中的行进行排序并赋予一个唯一的...

Global site tag (gtag.js) - Google Analytics