Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle SQL和#x27;保持';对于多列和';保持';一人一组,其他人一组?_Sql_Oracle_Oracle11g_Aggregate Functions - Fatal编程技术网

Oracle SQL和#x27;保持';对于多列和';保持';一人一组,其他人一组?

Oracle SQL和#x27;保持';对于多列和';保持';一人一组,其他人一组?,sql,oracle,oracle11g,aggregate-functions,Sql,Oracle,Oracle11g,Aggregate Functions,我刚刚学习了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 |

我刚刚学习了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)  
我想按person、branch和year返回最新时间戳的行,即第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, 
    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;
但我正在学习我可以写这个:

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;
我担心的是,我发现的许多文档和示例并没有将所有的GROUPBY列都放在GROUPBY中,而是为许多列编写了KEEP语句

像这样:

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, 
    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、年份和分支机构的时间戳上永远不会有重复项,我可以用第一种方式写它,还是仍然需要用第二种方式写。使用第一种方法,我得到了我所期望的结果,但是我似乎找不到任何关于这种方法的解释,也找不到区别


有吗

您的聚合查询不同。如果您有:

GROUP BY a.PERSON_ID, a.YEAR, a.BRANCH
对于这三列的每个组合,结果集中将有一行

如果您指定:

GROUP BY a.PERSON_ID
然后,每个
个人ID
只对应一行。在某些情况下,这与上述版本相同。但仅当每个
个人ID有一个
分支机构
时。这在你的数据中是不正确的


这些版本在功能上与具有相关子查询的版本在大多数实际用途上是等效的。一个区别是,如果任何分组/相关列为
NULL
,会发生什么情况。
分组依据
保留这些分组。相关子查询将它们过滤掉。

抱歉,我开始键入,并意识到3列不是一个好例子,哈哈。因此,如果我得到相同的结果,这可能是巧合。就我目前的目标而言,我应该使用GROUP BY中的3列,对吗?我看到的让我质疑自己的例子是这个博客:。它对除一列之外的所有列使用KEEP,但似乎具有相同的预期结果。