Oracle SQL查询:根据时间检索每个组的最新值

Oracle SQL query: Retrieve latest values per group based on time

本问题已经有最佳答案,请猛点这里访问。

我在Oracle DB中有下表

1
2
3
4
5
6
7
8
9
10
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的最新值(及其时间)。 示例输出:

1
2
3
4
5
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)。

非常感谢您的帮助!


鉴于此数据......

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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>

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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子句应用其他过滤器。 类似地,您可以将其他表连接到内联视图,就像任何其他表一样。


这是一个完整的,经过测试的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
2
3
4
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):

1
2
3
4
5
6
7
8
9
10
11
   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;