Oracle SQL查询:根据时间检索每组的最新值[重复]

Posted

技术标签:

【中文标题】Oracle SQL查询:根据时间检索每组的最新值[重复]【英文标题】:Oracle SQL query: Retrieve latest values per group based on time [duplicate] 【发布时间】:2011-01-01 08:03:59 【问题描述】:

我在 Oracle 数据库中有下表

id     date              quantity
1      2010-01-04 11:00  152
2      2010-01-04 11:00  210
1      2010-01-04 10:45  132
2      2010-01-04 10:45  318
4      2010-01-04 10:45  122
1      2010-01-04 10:30  1
3      2010-01-04 10:30  214
2      2010-01-04 10:30  5515
4      2010-01-04 10:30  210

现在我想检索每个 id 的最新值(及其时间)。示例输出:

id     date              quantity
1      2010-01-04 11:00  152
2      2010-01-04 11:00  210
3      2010-01-04 10:30  214
4      2010-01-04 10:45  122

我只是不知道如何将其放入查询中...

此外,以下选项会很好:

选项 1:查询应该只返回过去 XX 分钟的值。

选项 2:id 应该与另一个具有 id 和 idname 的表中的文本连接。 id 的输出应该是这样的:id-idname(例如 1-testid1)。

非常感谢您的帮助!

【问题讨论】:

对于给定的IDDATE 是唯一的吗? 时间戳应该是唯一的,但显然它不在我可用的数据中——所以无论如何解决方案都应该有效。 【参考方案1】:

鉴于这些数据...

SQL> select * from qtys
  2  /

        ID TS                      QTY
---------- ---------------- ----------
         1 2010-01-04 11:00        152
         2 2010-01-04 11:00        210
         1 2010-01-04 10:45        132
         2 2010-01-04 10:45        318
         4 2010-01-04 10:45        122
         1 2010-01-04 10:30          1
         3 2010-01-04 10:30        214
         2 2010-01-04 10:30       5515
         4 2010-01-04 10:30        210

9 rows selected.

SQL>

...以下查询给出了您想要的...

SQL> select x.id
  2         , x.ts as "DATE"
  3         , x.qty as "QUANTITY"
  4  from (
  5      select id
  6             , ts
  7             , rank () over (partition by id order by ts desc) as rnk
  8             , qty
  9      from qtys ) x
 10  where x.rnk = 1
 11  /

        ID DATE               QUANTITY
---------- ---------------- ----------
         1 2010-01-04 11:00        152
         2 2010-01-04 11:00        210
         3 2010-01-04 10:30        214
         4 2010-01-04 10:45        122

SQL>

关于您的其他要求,您可以将其他过滤器应用于外部 WHERE 子句。同样,您可以将其他表连接到内联视图,就像它是任何其他表一样。

【讨论】:

谢谢,基本查询工作正常。刚刚发现时间戳并不总是唯一的,所以我每个 id 都有多个条目,但是在开头添加一个 DISTINCT 会有所帮助。现在将尝试其他选项。 将 DISTINCT 添加到内部或外部选择中会更好吗? DISTINCT 不会改变您获得的结果,除非 quantity 值偶然匹配最大 date 值。您需要发现合适的业务规则是什么,并应用它。可能包括max(quantity)min(quantity)avg(quantity),但有许多可能的解决方案。 它们在时间戳和数量上都是重复的,所以不同的作品。在相关说明中,是否有比以下查询更有效的方法来仅从 oracle 数据库中检索单个最新记录:. select * from (select number from table order by time desc) where ROWNUM Tom - 这听起来像是你应该提出的一个新问题。【参考方案2】:

这是一个完整的、经过测试的示例。

CREATE TABLE tbl1 (ID NUMBER, dt DATE, quantity NUMBER);

DELETE FROM tbl1;
insert into tbl1 values (1,to_date('2010-01-04 11:00','YYYY-MM-DD HH24:MI'), 152);
insert into tbl1 values (2,to_date('2010-01-04 11:00','YYYY-MM-DD HH24:MI'), 210);
insert into tbl1 values (1,to_date('2010-01-04 10:45','YYYY-MM-DD HH24:MI'), 132);
insert into tbl1 values (2,to_date('2010-01-04 10:45','YYYY-MM-DD HH24:MI'), 318);
insert into tbl1 values (4,to_date('2010-01-04 10:45','YYYY-MM-DD HH24:MI'), 122);
insert into tbl1 values (1,to_date('2010-01-04 10:30','YYYY-MM-DD HH24:MI'), 1);
insert into tbl1 values (3,to_date('2010-01-04 10:30','YYYY-MM-DD HH24:MI'), 214);
insert into tbl1 values (2,to_date('2010-01-04 10:30','YYYY-MM-DD HH24:MI'), 5515);
insert into tbl1 values (4,to_date('2010-01-04 10:30','YYYY-MM-DD HH24:MI'), 210);

SELECT t.ID
     , t.DT
     , t.QUANTITY
  FROM tbl1 t
     ,( SELECT ID
             , MAX(dt) dt
          FROM tbl1
       GROUP BY ID ) t2
  WHERE t.id = t2.id
    AND t.dt = t2.dt

结果:

1   1/4/2010 11:00:00 AM    152
2   1/4/2010 11:00:00 AM    210
3   1/4/2010 10:30:00 AM    214
4   1/4/2010 10:45:00 AM    122

如果您想获取最后 XX 分钟的记录,您可以这样做(在此示例中我使用 500 分钟,将 500 替换为您想要的任何内容):

   SELECT t.ID
        , t.DT
        , t.QUANTITY
     FROM tbl1 t
        ,( SELECT ID
                , MAX(dt) dt
             FROM tbl1
            WHERE dt >= SYSDATE - (500 / 1400)
          GROUP BY ID ) t2
     WHERE t.id = t2.id
       AND t.dt = t2.dt;

【讨论】:

我也投票给你的答案,我只是更喜欢其他语句的语法。

以上是关于Oracle SQL查询:根据时间检索每组的最新值[重复]的主要内容,如果未能解决你的问题,请参考以下文章

SQL:如何在 sql 中找到每组的最小值?

ORACLE分组排序查询

根据最大日期获取每组的最新行

Oracle分组查询取每组排序后的前N条记录

Doctrine Query Language 获取每组的最大/最新行

Oracle sql查询需要根据时区变化