【问题标题】:每小时选择最新员工条目的 Oracle SQL 查询
【发布时间】:2021-11-26 22:22:00
【问题描述】:

我将如何修改以下 SQL 查询代码以每小时返回每个员工的最新条目,而不是当前返回每个员工的每个事件,无论它每小时在查询中出现多少次。

我已附上示例数据,以说明当前在数据库中的顺序和所需的表输出。注意:您可以看到它是按降序排列的,并且省略了 2 个条目(0001 和 0009),因为它们在一个小时内来自同一员工。

SQL查询代码:

select
     TRANSACTION_ID
     EMPLOYEE_ID
     FIRST_NAME
     LAST_NAME
     TIME_STAMP
from (select d.*,
             row_number() over (partition by EMPLOYEE_ID, trunc(TIME_STAMP, 'HH') order by TIME_STAMP desc) as SEQNUM
      from MAIN.DATABASE d
     ) d
where SEQNUM = 1;
order by TRANSACTION_ID desc;

这是数据库中数据的当前顺序:

TRANSACTION_ID EMPLOYEE_ID FIRST_NAME LAST_NAME TIME_STAMP
0001 AAAA Adam Akbar 10/05/2021 04:42:42.000 PM
0004 BBBB Barry Brink 10/06/2021 07:25:25.000 AM
0003 CCCC Charlie Che 10/06/2021 07:15:15.000 AM
0005 DDDD David Doe 10/06/2021 07:27:27.000 AM
0006 EEEE Eric Erickson 10/06/2021 07:29:29.000 AM
0007 FFFF Fred Foe 10/06/2021 07:31:31.000 AM
0008 GGGG George Guy 10/06/2021 07:33:33.000 AM
0010 HHHH Henry Hugh 10/06/2021 07:55:55.000 AM
0009 HHHH Henry Hugh 10/06/2021 07:54:54.000 AM
0002 AAAA Adam Akbar 10/05/2021 04:43:43.000 PM

这是应该返回的:

TRANSACTION_ID EMPLOYEE_ID FIRST_NAME LAST_NAME TIME_STAMP
0010 HHHH Henry Hugh 10/06/2021 07:55:55.000 AM
0008 GGGG George Guy 10/06/2021 07:33:33.000 AM
0007 FFFF Fred Foe 10/06/2021 07:31:31.000 AM
0006 EEEE Eric Erickson 10/06/2021 07:29:29.000 AM
0005 DDDD David Doe 10/06/2021 07:27:27.000 AM
0004 BBBB Barry Brink 10/06/2021 07:25:25.000 AM
0003 CCCC Charlie Che 10/06/2021 07:15:15.000 AM
0002 AAAA Adam Akbar 10/05/2021 04:43:43.000 PM

但是,这是代码当前返回的内容:

TRANSACTION_ID EMPLOYEE_ID FIRST_NAME LAST_NAME TIME_STAMP
0010 HHHH Henry Hugh 10/06/2021 07:55:55.000 AM
0006 EEEE Eric Erickson 10/06/2021 07:29:29.000 AM
0003 CCCC Charlie Che 10/06/2021 07:15:15.000 AM
0002 AAAA Adam Akbar 10/05/2021 04:43:43.000 PM

知道我缺少什么以及如何解决它吗?

【问题讨论】:

    标签: sql oracle greatest-n-per-group


    【解决方案1】:

    查询(为了返回你想要的)应该这样工作。但是,我假设您的字段 time_stamp 确实是您提供的格式的时间戳。

    SQL> set lines 220
    SQL> with x ( transaction_id , employee_id, first_name, last_name, time_stamp )
      2  as
      3  (
      4  select '0001' , 'AAAA', 'Adam'       , 'Akbar'     , to_timestamp('10/05/2021 04:42:42.000 PM','MM/DD/YYYY HH:MI:SS.FF3 PM') from dual union all
      5  select '0004' , 'BBBB', 'Barry'      , 'Brink'     , to_timestamp('10/06/2021 07:25:25.000 AM','MM/DD/YYYY HH:MI:SS.FF3 AM') from dual union all
      6  select '0003' , 'CCCC', 'Charlie' , 'Che'      , to_timestamp('10/06/2021 07:15:15.000 AM','MM/DD/YYYY HH:MI:SS.FF3 AM') from dual union all
      7  select '0005' , 'DDDD', 'David'      , 'Doe'           , to_timestamp('10/06/2021 07:27:27.000 AM','MM/DD/YYYY HH:MI:SS.FF3 AM') from dual union all
      8  select '0006' , 'EEEE', 'Eric'       , 'Erickson'  , to_timestamp('10/06/2021 07:29:29.000 AM','MM/DD/YYYY HH:MI:SS.FF3 AM') from dual union all
      9  select '0007' , 'FFFF', 'Fred'       , 'Foe'           , to_timestamp('10/06/2021 07:31:31.000 AM','MM/DD/YYYY HH:MI:SS.FF3 AM') from dual union all
     10  select '0008' , 'GGGG', 'George'  , 'Guy'      , to_timestamp('10/06/2021 07:33:33.000 AM','MM/DD/YYYY HH:MI:SS.FF3 AM') from dual union all
     11  select '0010' , 'HHHH', 'Henry'      , 'Hugh'          , to_timestamp('10/06/2021 07:55:55.000 AM','MM/DD/YYYY HH:MI:SS.FF3 AM') from dual union all
     12  select '0009' , 'HHHH', 'Henry'      , 'Hugh'          , to_timestamp('10/06/2021 07:54:54.000 AM','MM/DD/YYYY HH:MI:SS.FF3 AM') from dual union all
     13  select '0002' , 'AAAA', 'Adam'       , 'Akbar'         , to_timestamp('10/05/2021 04:43:43.000 PM','MM/DD/YYYY HH:MI:SS.FF3 PM') from dual
     14  )
     15  select
     16       TRANSACTION_ID ,
     17       EMPLOYEE_ID    ,
     18       FIRST_NAME     ,
     19       LAST_NAME      ,
     20       TIME_STAMP
     21  from (select x.*,
     22               row_number() over (partition by EMPLOYEE_ID, trunc(TIME_STAMP, 'HH') order by TIME_STAMP desc) as SEQNUM
     23        from x
     24       )
     25  where SEQNUM = 1
     26* order by TRANSACTION_ID desc
    
    TRAN EMPL FIRST_N LAST_NAM TIME_STAMP
    ---- ---- ------- -------- ---------------------------------------------------------------------------
    0010 HHHH Henry   Hugh     06-OCT-21 07.55.55.000000000 AM
    0008 GGGG George  Guy      06-OCT-21 07.33.33.000000000 AM
    0007 FFFF Fred    Foe      06-OCT-21 07.31.31.000000000 AM
    0006 EEEE Eric    Erickson 06-OCT-21 07.29.29.000000000 AM
    0005 DDDD David   Doe      06-OCT-21 07.27.27.000000000 AM
    0004 BBBB Barry   Brink    06-OCT-21 07.25.25.000000000 AM
    0003 CCCC Charlie Che      06-OCT-21 07.15.15.000000000 AM
    0002 AAAA Adam    Akbar    05-OCT-21 04.43.43.000000000 PM
    
    8 rows selected.
    
    SQL>
    

    【讨论】:

      【解决方案2】:

      您的查询是:

      • SELECT 子句中的术语之间缺少逗号;和
      • WHERE 过滤器之后和ORDER BY 子句之前有一个;

      如果你解决了这些问题,那么你会得到代码:

      select TRANSACTION_ID,
             EMPLOYEE_ID,
             FIRST_NAME,
             LAST_NAME,
             TIME_STAMP
      from   (
        select d.*,
               row_number() over (
                 partition by EMPLOYEE_ID, trunc(TIME_STAMP, 'HH')
                 order by TIME_STAMP desc
               ) as SEQNUM
        from   MAIN.DATABASE d
      ) d
      where  SEQNUM = 1
      order by TRANSACTION_ID desc;
      

      其中,对于样本数据:

      CREATE TABLE main.database (TRANSACTION_ID, EMPLOYEE_ID, FIRST_NAME, LAST_NAME, TIME_STAMP ) AS
      SELECT '0001', 'AAAA', 'Adam',    'Akbar',    TIMESTAMP '2021-05-10 16:42:42.000' FROM DUAL UNION ALL
      SELECT '0004', 'BBBB', 'Barry',   'Brink',    TIMESTAMP '2021-06-10 07:25:25.000' FROM DUAL UNION ALL
      SELECT '0003', 'CCCC', 'Charlie', 'Che',      TIMESTAMP '2021-06-10 07:15:15.000' FROM DUAL UNION ALL
      SELECT '0005', 'DDDD', 'David',   'Doe',      TIMESTAMP '2021-06-10 07:27:27.000' FROM DUAL UNION ALL
      SELECT '0006', 'EEEE', 'Eric',    'Erickson', TIMESTAMP '2021-06-10 07:29:29.000' FROM DUAL UNION ALL
      SELECT '0007', 'FFFF', 'Fred',    'Foe',      TIMESTAMP '2021-06-10 07:31:31.000' FROM DUAL UNION ALL
      SELECT '0008', 'GGGG', 'George',  'Guy',      TIMESTAMP '2021-06-10 07:33:33.000' FROM DUAL UNION ALL
      SELECT '0010', 'HHHH', 'Henry',   'Hugh',     TIMESTAMP '2021-06-10 07:55:55.000' FROM DUAL UNION ALL
      SELECT '0009', 'HHHH', 'Henry',   'Hugh',     TIMESTAMP '2021-06-10 07:54:54.000' FROM DUAL UNION ALL
      SELECT '0002', 'AAAA', 'Adam',    'Akbar',    TIMESTAMP '2021-05-10 16:43:43.000' FROM DUAL;
      

      按预期工作:

      TRANSACTION_ID EMPLOYEE_ID FIRST_NAME LAST_NAME TIME_STAMP
      0010 HHHH Henry Hugh 10-JUN-21 07.55.55.000000000
      0008 GGGG George Guy 10-JUN-21 07.33.33.000000000
      0007 FFFF Fred Foe 10-JUN-21 07.31.31.000000000
      0006 EEEE Eric Erickson 10-JUN-21 07.29.29.000000000
      0005 DDDD David Doe 10-JUN-21 07.27.27.000000000
      0004 BBBB Barry Brink 10-JUN-21 07.25.25.000000000
      0003 CCCC Charlie Che 10-JUN-21 07.15.15.000000000
      0002 AAAA Adam Akbar 10-MAY-21 16.43.43.000000000

      db小提琴here

      【讨论】:

      • 您好 MT0,感谢您的回复。我做了这些更正,但是,查询返回 0 个条目。我意识到这是因为在这种情况下,正确条目的 SEQNUM = 2(对于我们想要丢弃的条目,SEQNUM = 3),但在其他数据集中,好的 SEQNUM 条目 = 1(而坏的 SEQNUM 条目 = 2)。您是否知道在此代码中合并 [MAX(SEQNUM) - 1] 变量以在任何情况下标准化此代码的方法?
      猜你喜欢
      • 2021-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      相关资源
      最近更新 更多