如何保留每个组中最新项目的所有记录

时间:2017-07-18 19:57:35

标签: sql oracle dense-rank

我有一个Oracle数据库,每行包含

  • 乘客飞行的航班号(PLNR)
  • 航班日期(PLDATE)
  • 乘客的机票号码(TKTNUM)

示例内容:

PLNR    PLDATE      TKTNUM
100     10/01/2017  1234
100     11/01/2017  1235
100     11/01/2017  1236
200     9/01/2017   7890
200     10/01/2017  7891
200     10/01/2017  5678

我想在每个航班号的最新航班上保留所有机票号码。

示例输出:

PLNR    PLDATE      TKTNUM
100     11/01/2017  1235
100     11/01/2017  1236
200     10/01/2017  7891
200     10/01/2017  5678

我在网上搜索并发现了一些帖子建议使用dense_rank并保持优先,但我正在努力结合多个标准(例如,PLDATE和PLNR)来获取多个记录。

您能否建议一个解决方案,更重要的是,解释它是如何工作的? (我正在翻译这个)。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

使用:

Java 8
apache-servicemix 7.0.1

答案 1 :(得分:0)

WITH CTE AS (SELECT PLNR, PLDATE, TKTNUM
                  , Dense_Rank ()Over (partition by PLNR, Trunc(PLDATE) order by PLDATE DESC) DR)
SELECT * 
FROM cte 
WHERE DR= 1

需要CTE或子查询,因为在我们可以限制之前,DR必须在内存中实现。

over语法是一个分析函数,它为每个分区分配一个顺序排名(按日期降序排序的PLNR和trunc(PLDATE)。由于我们使用的是dense_rank函数,因此相同的日期将被赋予相同的值。因此,最新的PLDate将始终具有每plnr / PLDATE 1的等级。

因此CTE结果如下:

PLNR    PLDATE      TKTNUM DR
100     10/01/2017  1234   2
100     11/01/2017  1235   1
100     11/01/2017  1236   1
200     9/01/2017   7890   2
200     10/01/2017  7891   1
200     10/01/2017  5678   1

我们只保留1对CTE的选择。

现在我在PLDATE上使用了Trunc,它包含一个时间组件,因为我们不希望那些混乱的东西;因为oracle通常会在输入时存储两者。