【问题标题】:Finding latest record entry [closed]查找最新记录条目[关闭]
【发布时间】:2013-11-28 08:10:20
【问题描述】:

我有这样的数据。

REPORTER    SUMMARY                CREATED          UPDATED status  servicetype  
e159299 Route card from August  7/29/2013   22:46.0    5    New Route Card
e159299 I have returned the     6/11/2013   32:09.7    5    Cancel Route Card
e159324 New Route Card: RBI     1/2/2013    00:51.0    5    New Route Card
e159324 Hi, I would require     10/30/2013  35:23.0    5    New Route Card
e159299 Cancel Route Card       4/30/2013   53:26.2    5    Cancel Route Card

我需要获取给定记者的最新记录条目。 即我需要为记者进行分组,并且需要获取合并创建字段的最新记录。

我的输出一定是这样的。

 e159299    Route card from August  7/29/2013   22:46.0    5    New Route Card  
 e159324    Hi, I would require     10/30/2013  35:23.0    5    New Route Card

【问题讨论】:

  • 哇,你没有使用 DATETIME 列真是太糟糕了(要么是那个,要么是一个非常有趣的自定义格式正在被应用)。
  • 您能否澄清一下CREATED/UPDATED 列的情况?具体来说——它们是什么数据类型?

标签: sql oracle analytic-functions


【解决方案1】:

分析函数非常适合此类查询:

select *
from (
   select reporter
   ,      summary
   ,      created
   ,      updated_status
   ,      servicetype
   ,      max(created) over (partition by reporter) last_created
   from   yout_table t)
where created = last_created;

【讨论】:

    【解决方案2】:

    为此设计了分析函数 - 只需 GROUP BY 适当的列(在本例中为 REPORTER)并在其他每一行上使用 MAX( <column_name> ) KEEP ( DENSE_RANK LAST ORDER BY <ordering_column> )

    SQL Fiddle

    Oracle 11g R2 架构设置

    CREATE TABLE tbl ( REPORTER, SUMMARY, CREATED, UPDATED, status, servicetype ) AS
              SELECT 'e159299', 'Route card from August', '7/29/2013',  '22:46.0', 5, 'New Route Card' FROM DUAL
    UNION ALL SELECT 'e159299', 'I have returned the',    '6/11/2013',  '32:09.7', 5, 'Cancel Route Card' FROM DUAL
    UNION ALL SELECT 'e159324', 'New Route Card: RBI',    '1/2/2013',   '00:51.0', 5, 'New Route Card' FROM DUAL
    UNION ALL SELECT 'e159324', 'Hi, I would require',    '10/30/2013', '35:23.0', 5, 'New Route Card' FROM DUAL
    UNION ALL SELECT 'e159299', 'Cancel Route Card',      '4/30/2013',  '53:26.2', 5, 'Cancel Route Card' FROM DUAL;
    

    查询 1

    SELECT REPORTER,
           MAX( SUMMARY     ) KEEP ( DENSE_RANK LAST ORDER BY TO_DATE( CREATED, 'MM/DD/YYYY' ) ) AS SUMMARY,
           MAX( CREATED     ) KEEP ( DENSE_RANK LAST ORDER BY TO_DATE( CREATED, 'MM/DD/YYYY' ) ) AS CREATED,
           MAX( UPDATED     ) KEEP ( DENSE_RANK LAST ORDER BY TO_DATE( CREATED, 'MM/DD/YYYY' ) ) AS UPDATED,
           MAX( status      ) KEEP ( DENSE_RANK LAST ORDER BY TO_DATE( CREATED, 'MM/DD/YYYY' ) ) AS status,
           MAX( servicetype ) KEEP ( DENSE_RANK LAST ORDER BY TO_DATE( CREATED, 'MM/DD/YYYY' ) ) AS servicetype
    FROM tbl
    GROUP BY REPORTER
    

    Results

    | REPORTER |                SUMMARY |    CREATED | UPDATED | STATUS |    SERVICETYPE |
    |----------|------------------------|------------|---------|--------|----------------|
    |  e159299 | Route card from August |  7/29/2013 | 22:46.0 |      5 | New Route Card |
    |  e159324 |    Hi, I would require | 10/30/2013 | 35:23.0 |      5 | New Route Card |
    

    【讨论】:

    • 哇,这看起来比它需要的复杂。我更喜欢@Alen 的回答,其中只有一个分析函数需要处理。您还可以使用什么其他功能(也可能产生更独特的结果)?
    • 如果您比较执行计划,那么这实际上比@Alen 的解决方案更有效。还有其他方法可以重写它,但我还没有找到比这成本更低的执行计划。
    【解决方案3】:

    试试这个...

    SELECT * FROM table ORDER BY CREATED DESC LIMIT 0,2

    这个查询是针对mysql数据库的

    【讨论】:

    • ...OP 指定他有一个 Oracle DB,所以你给他一个 MySQL 查询?请注意,虽然这适用于样本数据,但这不太可能解决他的实际问题;这只会选择最后两行,而且他可能有更多的记者。
    猜你喜欢
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 1970-01-01
    • 2012-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多