Oracle"Partition By"关键字

Ale*_*ley 242 sql oracle window-functions

有人可以解释partition by关键字的作用并给出一个简单的例子,以及为什么人们会想要使用它?我有一个由其他人编写的SQL查询,我正在试图找出它的作用.

分区示例:

SELECT empno, deptno, COUNT(*) 
OVER (PARTITION BY deptno) DEPT_COUNT
FROM emp
Run Code Online (Sandbox Code Playgroud)

我在网上看到的例子似乎有点过于深入.

Guy*_*Guy 248

PARTITION BY子句设置将用于OVER子句中每个"GROUP"的记录范围.

在您的示例SQL中,DEPT_COUNT将返回该部门中每个员工记录的员工数.(就像你对emp表格进行去正规化一样;你仍然会返回emp表格中的每条记录.)

emp_no  dept_no  DEPT_COUNT
1       10       3
2       10       3
3       10       3 <- three because there are three "dept_no = 10" records
4       20       2
5       20       2 <- two because there are two "dept_no = 20" records
Run Code Online (Sandbox Code Playgroud)

如果有另一列(例如state),那么您可以计算该州有多少个部门.

它像得到的结果GROUP BY(SUM,AVG等),而不结果集的聚集.

当您使用LAST OVERMIN OVER函数来获取部门中的最低和最高工资时,它会很有用,然后在没有子选择的情况下使用该计数来计算此记录工资,这要快得多.

阅读链接的AskTom文章了解更多详细信息.

  • LAST_VALUE - 返回最后一个薪水,MAX返回最高薪水 (5认同)
  • 你的意思是“没有子选择,这要慢得多”?我想我很困惑子选择是否比“last over”和“min over”慢或快。我想子选择会更慢,但答案中的英语语法并不表明这一点。 (2认同)

And*_*ejs 145

接受的答案很好地解释了这个概念,但我发现越多的例子就越好.它是一个增量的例子:

1)Boss说 "给我一些按品牌分类的库存物品"

你说:"没问题"

SELECT 
      BRAND
      ,COUNT(ITEM_ID) 
FROM 
      ITEMS
GROUP BY 
      BRAND;
Run Code Online (Sandbox Code Playgroud)

结果:

+--------------+---------------+
|  Brand       |   Count       | 
+--------------+---------------+
| H&M          |     50        |
+--------------+---------------+
| Hugo Boss    |     100       |
+--------------+---------------+
| No brand     |     22        |
+--------------+---------------+
Run Code Online (Sandbox Code Playgroud)

2)老板说 "现在给我一份所有商品的清单,包括他们的品牌和各自品牌的商品数量"

你可以尝试:

 SELECT 
      ITEM_NR
      ,BRAND
      ,COUNT(ITEM_ID) 
 FROM 
      ITEMS
 GROUP BY 
      BRAND;
Run Code Online (Sandbox Code Playgroud)

但你得到:

ORA-00979: not a GROUP BY expression 
Run Code Online (Sandbox Code Playgroud)

这是OVER (PARTITION BY BRAND)进来的地方:

 SELECT 
      ITEM_NR
      ,BRAND
      ,COUNT(ITEM_ID) OVER (PARTITION BY BRAND) 
 FROM 
      ITEMS;
Run Code Online (Sandbox Code Playgroud)

这意味着:

  • COUNT(ITEM_ID) - 获取物品数量
  • OVER - 在行集上
  • (PARTITION BY BRAND) - 拥有相同的品牌

结果是:

+--------------+---------------+----------+
|  Items       |  Brand        | Count()  |
+--------------+---------------+----------+
|  Item 1      |  Hugo Boss    |   100    | 
+--------------+---------------+----------+
|  Item 2      |  Hugo Boss    |   100    | 
+--------------+---------------+----------+
|  Item 3      |  No brand     |   22     | 
+--------------+---------------+----------+
|  Item 4      |  No brand     |   22     | 
+--------------+---------------+----------+
|  Item 5      |  H&M          |   50     | 
+--------------+---------------+----------+
Run Code Online (Sandbox Code Playgroud)

等等...

  • 如果我想为每个小组得到一个结果..我怎么能得到它? (3认同)

小智 27

它是名为analytics的SQL扩展.select语句中的"over"告诉oracle该函数是一个分析函数,而不是按函数分组.使用分析的优势在于,只需一次传递数据就可以收集总和,计数等等,而不是使用子选择或更糟糕的PL/SQL循环数据.

它起初看起来确实令人困惑,但这很快就会成为第二天性.没有人比Tom Kyte更好地解释它.所以上面的链接很棒.

当然,阅读文档是必须的.


小智 10

EMPNO     DEPTNO DEPT_COUNT
Run Code Online (Sandbox Code Playgroud)
 7839         10          4
 5555         10          4
 7934         10          4
 7782         10          4 --- 4 records in table for dept 10
 7902         20          4
 7566         20          4
 7876         20          4
 7369         20          4 --- 4 records in table for dept 20
 7900         30          6
 7844         30          6
 7654         30          6
 7521         30          6
 7499         30          6
 7698         30          6 --- 6 records in table for dept 30
Run Code Online (Sandbox Code Playgroud)

在这里,我们正在计算各自的deptno.至于deptno 10,我们在表emp中有4条记录,对于deptno 20和30也有类似的结果.

  • 没有对PARTITION如何运作的问题进行过期.仅仅是示例输出并不能完全回答这个问题. (12认同)