sql - 多列的 Oracle SQL 'KEEP' 和一列的 'KEEP' 和其余的 GROUP BY 之间有区别吗?
问题描述
我刚刚在 Oracle SQL 中学习 KEEP,但我似乎找不到解释为什么他们的示例在所有未编入索引的列中使用 KEEP 的文档。
我有一张有 5 列的表
PERSON_ID | BRANCH | YEAR | STATUS | TIMESTAMP
123456 | 0001 | 2017 | 1 | 1-1-2017 (ROW 1)
123456 | 0001 | 2017 | 2 | 2-1-2017 (ROW 2)
123456 | 0002 | 2017 | 3 | 3-1-2017 (ROW 3)
123456 | 0001 | 2017 | 2 | 4-1-2017 (ROW 4)
123456 | 0001 | 2018 | 2 | 1-1-2018 (ROW 5)
123456 | 0001 | 2018 | 3 | 2-1-2018 (ROW 6)
我想按人、分支和年份返回最新时间戳的行,所以第 3、4 和 6 行。
RESULTS
PERSON_ID | BRANCH | YEAR | STATUS | TIME_STAMP
123456 | 0002 | 2017 | 3 | 3-1-2017 (ROW 3)
123456 | 0001 | 2017 | 2 | 4-1-2017 (ROW 4)
123456 | 0001 | 2018 | 3 | 2-1-2018 (ROW 6)
为了得到整行,我通常会写这样的东西:
SELECT *
FROM STATUS_TABLE a
WHERE a.TIME_STAMP =
(
SELECT MAX(sub.TIME_STAMP)
FROM STATUS_TABLE sub
WHERE a.PERSON_ID = sub.PERSON_ID
AND a.YEAR = sub.YEAR
AND a.BRANCH = sub.BRANCH
)
但我正在学习我可以这样写:
SELECT
a.PERSON_ID,
a.YEAR,
a.BRANCH,
MAX(a.STATUS) KEEP (DENSE_RANK FIRST ORDER BY TIME_STAMP DESC)
FROM STATUS_TABLE a
GROUP BY a.PERSON_ID, a.YEAR, a.BRANCH;
我担心的是,我发现的许多文档和示例并未将所有分组列放在 GROUP BY 中,而是为许多列编写了 KEEP 语句。
像这样:
SELECT
a.PERSON_ID,
MAX(a.YEAR) KEEP (DENSE_RANK FIRST ORDER BY TIME_STAMP DESC),
MAX(a.BRANCH) KEEP (DENSE_RANK FIRST ORDER BY TIME_STAMP DESC),
MAX(a.STATUS) KEEP (DENSE_RANK FIRST ORDER BY TIME_STAMP DESC)
FROM STATUS_TABLE a
GROUP BY a.PERSON_ID;
问题
如果我知道在 TIME_STAMP 上永远不会有 ID、YEAR 和 BRANCH 的重复项,我可以用第一种方式编写它,还是仍然需要用第二种方式编写它。使用第一种方法,我得到了我期望的结果,但我似乎找不到这种方法的任何解释以及可能存在的差异。
有吗?
解决方案
您的聚合查询是不同的。当你有:
GROUP BY a.PERSON_ID, a.YEAR, a.BRANCH
对于三列的每个组合,您的结果集中将有一行。
如果您指定:
GROUP BY a.PERSON_ID
然后每个只有一行PERSON_ID
。在某些情况下,这与上述版本相同。但只有当有 oneYEAR
和BRANCH
per时PERSON_ID
。在您的数据中并非如此。
对于大多数实际用途,这些版本在功能上等同于您的具有相关子查询的版本。一个区别是,如果任何分组/相关列是NULL
. GROUP BY
保留这些分组。相关子查询将它们过滤掉。
推荐阅读
- c - 按下键盘按钮时,PIC18 全局中断使能位切换
- java - Android RecyclerView - StaggeredGridLayoutManager 在滚动时弄乱了宽度
- python - 为图像熵重塑数组的 Valueerror
- java - JavaFX Canvas.setScaleX/Y(2) not scaling to twice the size
- linux - 如何检查 Kubernetes 作业是否正在运行
- string - 在 Azure 数据工厂中修改活动的输出
- java - 将数据从数据库存储到 bean
- regex - 正则表达式替换markdown文件的代码块标记中的所有空格
- node.js - 将文本转换为 PDF 并发送给用户下载
- mysql - 当我创建命令 sequelize 以创建关联表时,它将全部变为小写