我刚刚在学习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;
问题
如果我知道 ID、YEAR 和 BRANCH 在TIME_STAMP上永远不会有重复项,我可以用第一种方式写还是仍然需要用第二种方式写。使用第一种方法,我得到了我期望的结果,但我似乎找不到对这种方法的任何解释以及可能的差异。
有吗?
聚合查询是不同的。 当您有:
GROUP BY a.PERSON_ID, a.YEAR, a.BRANCH
对于三列的每个组合,结果集中的结果集中将有一行。
如果指定:
GROUP BY a.PERSON_ID
然后每个PERSON_ID
只有一行. 在某些情况下,这与上述版本相同。 但只有当每PERSON_ID
有一个YEAR
和BRANCH
. 在您的数据中并非如此。
出于大多数实际目的,这些版本在功能上等效于具有相关子查询的版本。 一个区别是,如果NULL
任何分组/相关列,会发生什么情况。GROUP BY
保留这些分组。 相关子查询会筛选出它们。