有人可以解释一下partition by
关键字的作用,并给出一个简单的示例,以及为什么要使用它吗?我有一个别人写的SQL查询,我试图弄清楚它的作用。
通过以下方式进行分区的示例:
SELECT empno, deptno, COUNT(*)
OVER (PARTITION BY deptno) DEPT_COUNT
FROM emp
我在网上看到的示例似乎过于深入。
有人可以解释一下partition by
关键字的作用,并给出一个简单的示例,以及为什么要使用它吗?我有一个别人写的SQL查询,我试图弄清楚它的作用。
通过以下方式进行分区的示例:
SELECT empno, deptno, COUNT(*)
OVER (PARTITION BY deptno) DEPT_COUNT
FROM emp
我在网上看到的示例似乎过于深入。
Answers:
该PARTITION BY
子句设置了该子句中每个“ GROUP”将使用的记录范围OVER
。
在您的示例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
如果还有另一列(例如state
),则可以计算该州的部门数。
这就像获取GROUP BY
(SUM
,AVG
等)的结果而不汇总结果集(即删除匹配的记录)一样。
当您使用LAST OVER
或MIN OVER
函数获取(例如)部门的最低和最高薪水,然后将其用于此记录薪水的计算中时,如果没有子选择,这将非常有用,这会更快。
阅读链接的AskTom文章以获取更多详细信息。
last over
和慢或快,我会感到困惑min over
。我以为子选择会比较慢,但是答案中的英语语法却没有建议。
公认的答案很好地解释了这个概念,但是我发现人们看到的例子越多,它的作用就越大。这是一个增量示例:
1)老板说 “让我按品牌分组的库存数量”
你说:“没问题”
SELECT
BRAND
,COUNT(ITEM_ID)
FROM
ITEMS
GROUP BY
BRAND;
结果:
+--------------+---------------+
| Brand | Count |
+--------------+---------------+
| H&M | 50 |
+--------------+---------------+
| Hugo Boss | 100 |
+--------------+---------------+
| No brand | 22 |
+--------------+---------------+
2)老板说: “现在让我得到所有物品的清单,以及它们的品牌和相应品牌拥有的物品数量”
您可以尝试:
SELECT
ITEM_NR
,BRAND
,COUNT(ITEM_ID)
FROM
ITEMS
GROUP BY
BRAND;
但是你得到:
ORA-00979: not a GROUP BY expression
这是OVER (PARTITION BY BRAND)
进来的地方:
SELECT
ITEM_NR
,BRAND
,COUNT(ITEM_ID) OVER (PARTITION BY BRAND)
FROM
ITEMS;
意思是:
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 |
+--------------+---------------+----------+
等等...
EMPNO DEPTNO DEPT_COUNT
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
在这里,我们正在获得各自的部门编号。至于deptno 10,我们在表emp中有4条记录,对于deptno 20和30也有类似的结果。
我认为,该示例暗示了分区工作方式和分组方式的细微差别。我的示例来自Oracle 12,如果我的示例恰巧是一个编译错误。
我试过了 :
SELECT t.data_key
, SUM ( CASE when t.state = 'A' THEN 1 ELSE 0 END)
OVER (PARTITION BY t.data_key) count_a_rows
, SUM ( CASE when t.state = 'B' THEN 1 ELSE 0 END)
OVER (PARTITION BY t.data_key) count_b_rows
, SUM ( CASE when t.state = 'C' THEN 1 ELSE 0 END)
OVER (PARTITION BY t.data_key) count_c_rows
, COUNT (1) total_rows
from mytable t
group by t.data_key ---- This does not compile as the compiler feels that t.state isn't in the group by and doesn't recognize the aggregation I'm looking for
但是,这按预期工作:
SELECT distinct t.data_key
, SUM ( CASE when t.state = 'A' THEN 1 ELSE 0 END)
OVER (PARTITION BY t.data_key) count_a_rows
, SUM ( CASE when t.state = 'B' THEN 1 ELSE 0 END)
OVER (PARTITION BY t.data_key) count_b_rows
, SUM ( CASE when t.state = 'C' THEN 1 ELSE 0 END)
OVER (PARTITION BY t.data_key) count_c_rows
, COUNT (1) total_rows
from mytable t;
根据外部键“ data_key”产生每种状态下的元素数。因此,如果data_key ='APPLE'具有3行,其状态为'A',2行其状态为'B',一行具有状态'C',则'APPLE'的对应行将为'APPLE',3、2 ,1、6