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)。
非常感谢您的帮助!
【问题讨论】:
对于给定的ID
,DATE
是唯一的吗?
时间戳应该是唯一的,但显然它不在我可用的数据中——所以无论如何解决方案都应该有效。
【参考方案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查询:根据时间检索每组的最新值[重复]的主要内容,如果未能解决你的问题,请参考以下文章