惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

TaoSecurity Blog
TaoSecurity Blog
Jina AI
Jina AI
雷峰网
雷峰网
月光博客
月光博客
The GitHub Blog
The GitHub Blog
WordPress大学
WordPress大学
B
Blog RSS Feed
美团技术团队
C
CXSECURITY Database RSS Feed - CXSecurity.com
小众软件
小众软件
Security Latest
Security Latest
Microsoft Azure Blog
Microsoft Azure Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cybersecurity and Infrastructure Security Agency CISA
Last Week in AI
Last Week in AI
A
Arctic Wolf
Latest news
Latest news
Attack and Defense Labs
Attack and Defense Labs
I
Intezer
F
Fortinet All Blogs
罗磊的独立博客
MongoDB | Blog
MongoDB | Blog
Webroot Blog
Webroot Blog
S
Secure Thoughts
Help Net Security
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
V
Visual Studio Blog
P
Proofpoint News Feed
博客园 - 【当耐特】
P
Privacy International News Feed
V
Vulnerabilities – Threatpost
Stack Overflow Blog
Stack Overflow Blog
Know Your Adversary
Know Your Adversary
云风的 BLOG
云风的 BLOG
Hacker News: Ask HN
Hacker News: Ask HN
L
LINUX DO - 最新话题
H
Help Net Security
爱范儿
爱范儿
酷 壳 – CoolShell
酷 壳 – CoolShell
S
SegmentFault 最新的问题
Forbes - Security
Forbes - Security
T
Tailwind CSS Blog
量子位
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Tenable Blog
Cloudbric
Cloudbric
N
News and Events Feed by Topic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hugging Face - Blog
Hugging Face - Blog

博客园 - 大天使泰瑞尔

通过反射机制控制前台的数据项的显示和隐藏 IE 6下CSS浮动样式的问题 转载一篇拼SQL字符串的语句 ASP.NET 2.0 中控件的简单异步回调 新手基础知识专用 今天终于学会了从客户端调用Web Service 学会了ASP.NET 2.0中的数据批量更新 - 大天使泰瑞尔 - 博客园 数据结构学习(6):队列 数据结构学习(5):链表 数据结构学习(4):栈 数据结构学习(3):堆化优先队列 数据结构学习(2):汉诺塔问题 数据结构学习(1):搜索二叉树 冒泡算法的三种JavaScript表示 YUI学习(1):ToolTip的用法 XML学习失误系列(2):分清节点性质,使用nodeValue JavaScript&DHTML特效学习(1):MSN提示框 YUI的Drap&Drop对IE7不支持 Gmail邮箱可以直接注册了
由partition看窗口函数
大天使泰瑞尔 · 2009-04-21 · via 博客园 - 大天使泰瑞尔

    最近要完成一个项目,有一个查询可难住了笔者,无论是子查询还是分组,都没弄出来,还是基础知识不行啊。不过呢,可以查资料,最后用一个窗口函数解决了问题。由于开始的数据库是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

      需要指出的是,窗口函数经过了数据库专门的优化,所以性能较为优异,比标量子查询要好,所以应当尽量使用。