最近要完成一个项目,有一个查询可难住了笔者,无论是子查询还是分组,都没弄出来,还是基础知识不行啊。不过呢,可以查资料,最后用一个窗口函数解决了问题。由于开始的数据库是Access,后来笔者导成SQL Server的,一下子明白了很多。

数据库类似是这个样子滴:
Employee表的字段:
empId,englishName,depId
Department表的字段:
depId,deptName
需求是:查找出Department表的所有字段,但是在前面显示出该部门的人数。
就是这样:
peopleCount    depId deptName
25                     1       人力资源部
42                     2       市场营销部
一、分组的失败
首先说说分组的概念。根据关系数据库理论,分组的概念是(G,·,e ),其中G是聚集,·是二目运算,e是G的一个成员,SELECT和GROUP BY的关系如下:
(一)当使用聚集函数(例如count),对于SELECT 列表中的项,如果没有把它当做聚集函数的参数使用,必须是分组的一部分,例如有一个SQL语句:
SELECT depId
       ,count(*) as peopleCount
FROM Employee
那就必须在GROUP BY中出现deptId:
SELECT depId
       ,count(*) as peopleCount
FROM Employee 
GROUP BY depId
但是窗口函数是例外的,不必(也不能)出现在Group BY子句中。
而对于可能更改分组(或者聚集函数返回值,例如新的列),则一定要包含在GROUP BY子句之中。否则就会报错。
二、窗口函数
知道了分组的基本概念之后,理解窗口函数就容易了,与聚集函数一样,窗口函数也是针对元组(就是行)进行聚集,但是不像聚集函数那样只返回一个值(也就是聚集所有行,然后计算),窗口函数可以为每个分组返回多个值。执行聚集的元组(行组)是窗口。
例如第一个代码:select count(*) as cnt from Employee 这很容易,只返回一行,但是往往需要从不表示聚集或者其他聚集的行中访问这种聚集数据,窗口函数就解决了这个问题。例如下面的SQL语句表示用窗口函数从细节行访问聚集数据,就是员工总数:
SELECT EnglishName
       ,deptId
       ,count(*) over() as peopleCount
FROM Employee
ORDER BY 2
OVER关键字表明,把Count当成窗口函数,对于查询返回的每一行,它返回了表中所有行的计数,括号表示还可以接收一些条件来限定行数,即多一层聚集。
三、partition的使用
partition就可以成为那个括号中的条件,它能够定义行的分区或者分组,以完成聚集。空的括号表示分区是整个结果集。partition by是一个移动的GROUP BY,例如:
SELECT EnglishName
       ,depId
       count(*) over(partition by deptId) as peopleCount
FROM Employee
ORDER BY 2
通过partition by depId,为每个部门执行count同一个部门的每个count值相同。所以会返回很多相同的行,这时可以通过内联视图的方式进行解决:
SELECT DISTINCT EnglishName
                ,depId
                ,peopleCount
FROM
    (SELECT EnglishName
            ,depId
            ,count(*) over(partition by depId) as peopleCount
     FROM Employee
     ORDER BY 2
    ) x
如果要在Access中使用,由于Access不支持窗口函数,只能使用标量子查询,代码如下:
Code
SELECT DISTINCT EnglishName
                ,depId
                ,peopleCount
FROM
    (SELECT e.EnglishName
            ,e.depId
            ,(select count(*) from emp d where e.depId=d.depId) as peopleCount
     FROM Employee e,Department d
     ORDER BY 2
    ) x
需要指出的是,窗口函数经过了数据库专门的优化,所以性能较为优异,比标量子查询要好,所以应当尽量使用。

转载于:https://www.cnblogs.com/tyrael007/archive/2009/04/21/1440831.html

由partition看窗口函数相关推荐

  1. GaussDB分布式Stream执行计划详解

    点击上方"蓝字" 关注我们,享更多干货! GaussDB的分布式架构充分运用了每个节点的计算资源,且随着节点规模的扩大其整体性能也呈线性增长.为了实现分布式架构下性能和资源的最大化 ...

  2. python与SQL学习比较

    目录:python与SQL比较学习 数据字段包含:自增id,订单时间ts,用户id,订单id,订单金额 1.limit 查看全部数据或前n行数据 1.查看全部数据或前n行数据 查看全部数据,panda ...

  3. 使用SQL和Pandas计算累计百分比

    本文目录: 数据准备 MySQL 计算累计百分比 1.不分组情况 2.分组情况 Hive SQL计算累计百分比 1.不分组情况 2.分组情况 pandas计算累计百分比 1.不分组情况 cumsum函 ...

  4. 【SQL 初级语法 6】 SQL 高级处理

    目录 6 SQL 高级处理 6.1 窗口函数 1.窗口函数语法 2.语法的基本使用方法 -- 使用 rank 函数 3.无需指定 partition by 4.专用窗口函数的种类 5.窗口函数的适用范 ...

  5. 数据仓库开发 SQL 使用技巧总结

    mysql 数据结构 常用 innodb 存储为 B+ 树 特点 多路平衡树,m 个子树中间节点就包含 m 个元素,一个中间节点是一个 page(磁盘页) 默认 16 kb: 子节点保存了全部得元素, ...

  6. Hive个人笔记总结

    一.Hive概述 1.1 简介 Hive是一个数据仓库软件 Hive主要使用HQL(类sql)来分析已经存储在分布式设备(HDFS)上的数据 Hive的本质是将用户编写的HQL,转换为MR/spark ...

  7. MySQL Window Function Descriptions

    聚合函数是将多条记录聚合为一条,而窗口函数是每条记录都会执行 win_fn()over (partition by order by frame) as new_row, partition:分区,窗 ...

  8. UEFI与MBR区别

    转自:https://blog.csdn.net/qq_35605632/article/details/57080567 大硬盘和WIN8系统,让我们从传统的BIOS+MBR模式升级到UEFI+GP ...

  9. EFI与MBR启动的区别

     EFI与MBR启动的区别 大硬盘和WIN8系统,让我们从传统的BIOS+MBR模式升级到UEFI+GPT模式,现在购买的主流电脑,都是预装WIN8系统,为了更好的支持2TB硬盘 ,更快速的启动win ...

最新文章

  1. 【spring】springAop开发
  2. 阿里云 Aliplayer高级功能介绍(三):多字幕
  3. 使用Entity Framework code first, migration
  4. [luoguP1013] 进制位(搜索)
  5. 杭电4554 叛逆的小明
  6. Eclipse 使用 SVN 插件后修改用户方法汇总
  7. ISI CVPR journal ranking
  8. 基于php046学校固定资产管理系统
  9. 【Python】Python IDLE 设置清屏功能(清屏快捷键Ctrl+w,亲测通用)
  10. Audacity的替代品
  11. android 怎么改变字体颜色,安卓系统字体颜色修改教程
  12. springboot集成Swagger3.0
  13. 金九银十,测试思维面试题最新整理!
  14. 大数据-HADOOP高可用、联邦机制- 学习笔记 -BH4
  15. 利用pymupdf编辑修改pdf
  16. img 图片自适应大小
  17. C++ 命名空间,也有叫名称空间
  18. 三菱FX系列plc编程软件SWOPC-FXGP/WIN-C中文版下载
  19. 让我们看了泪流满面的经典台词
  20. 大数据架构师成长之路

热门文章

  1. LeetCode MySQL 1211. 查询结果的质量和占比
  2. LeetCode 533. 孤独像素 II
  3. LeetCode 286. 墙与门(BFS)
  4. LeetCode 817. 链表组件
  5. LeetCode 45. 跳跃游戏 II(贪心/BFS,难)
  6. 叛乱2正版怎么创服务器,Insurgency Linux Server 叛乱2创建服务器教程(转steam指南)
  7. 下列哪项属于正确的锁定计算机桌面,【2018年职称计算机考试WindowsXp练习题及答案1】- 环球网校...
  8. linux串口数据异常,linux串口知识深入--收到数据异常问题处理
  9. python输入十个数输出最大值_python输入十个数如何输出最大值
  10. python中主要内建函数