我有一个非常慢的查询,并尝试通过使用实例化视图来优化响应时间。但是有一部分与快速刷新的一般限制不兼容。 如何在没有DENSE_RANK的情况下重写它?
create table t (id,object_id,log_cre_date) as
select 1,2,to_date('18/5/2010, 08:00','dd/mm/yyyy, hh:mi') from dual union all
select 2,2,to_date('18/5/2010, 10:00','dd/mm/yyyy, hh mi') from dual union all
select 3,3,to_date('18/5/2010, 11:00','dd/mm/yyyy, hh mi') from dual union all
select 4,3,to_date('18/5/2010, 12:10','dd/mm/yyyy, hh mi') from dual union all
select 5,4,to_date('18/5/2010, 12:20','dd/mm/yyyy, hh mi') from dual union all
select 6,4,to_date('18/5/2010, 11:30','dd/mm/yyyy, hh mi') from dual;
SELECT
MAX(t.id) KEEP(DENSE_RANK FIRST ORDER BY log_cre_date ASC) id,
t.object_id
FROM
t
GROUP BY
t.object_id
答案 0 :(得分:1)
我不确定接受的答案是否可以快速刷新。这绝对是一个查询:
SELECT max(cast(to_char(t.log_cre_date,'YYYYMMDDHH24MISS') || lpad(t.id,30,'0') as varchar2(80))) maxid,
t.object_id,
COUNT(*) cnt
FROM t
GROUP BY t.object_id;
这个想法是将id
附加到log_cre_date
并采用串联的最大值。这样,您就可以提取以后需要的id
。
因此,要获得id
,您可以这样做:
SELECT to_char(substr(maxid,-30)) id, object_id
FROM your_materialized_view;
您可以考虑将其隐藏起来。
这是一个完整的例子:
DROP TABLE t;
create table t (id,object_id,log_cre_date) as
select 1,2,to_date('18/5/2010, 08:00','dd/mm/yyyy, hh:mi') from dual union all
select 2,2,to_date('18/5/2010, 10:00','dd/mm/yyyy, hh mi') from dual union all
select 3,3,to_date('18/5/2010, 11:00','dd/mm/yyyy, hh mi') from dual union all
select 4,3,to_date('18/5/2010, 12:10','dd/mm/yyyy, hh mi') from dual union all
select 5,4,to_date('18/5/2010, 12:20','dd/mm/yyyy, hh mi') from dual union all
select 6,4,to_date('18/5/2010, 11:30','dd/mm/yyyy, hh mi') from dual;
ALTER TABLE t MODIFY id NOT NULL;
ALTER TABLE t ADD CONSTRAINT t_pk PRIMARY KEY ( id );
--DROP MATERIALIZED VIEW LOG ON t;
CREATE MATERIALIZED VIEW LOG ON t WITH ROWID, PRIMARY KEY (OBJECT_ID, LOG_CRE_DATE) INCLUDING NEW VALUES;
COUNT(*)
。重要!--DROP MATERIALIZED VIEW t_mv;
CREATE MATERIALIZED VIEW t_mv
REFRESH FAST ON COMMIT AS
SELECT max(cast(to_char(t.log_cre_date,'YYYYMMDDHH24MISS') || lpad(t.id,30,'0') as varchar2(80))) maxid,
t.object_id,
COUNT(*) cnt
FROM t
GROUP BY t.object_id;
select to_number(substr(maxid,-30)) id, object_id
from t_mv;
+----+-----------+ | ID | OBJECT_ID | +----+-----------+ | 2 | 2 | | 4 | 3 | | 5 | 4 | +----+-----------+
DELETE FROM t WHERE id = 5;
COMMIT;
select to_number(substr(maxid,-30)) id, object_id
from t_mv;
+----+-----------+ | ID | OBJECT_ID | +----+-----------+ | 4 | 3 | | 5 | 4 | | 1 | 2 | -- Now ID #1 is the latest for object_id 2 +----+-----------+
答案 1 :(得分:0)
我遇到了限制,但不确定以下查询是否有效。
尝试一下,让我们知道它是否有效。
Select t.id, t.object_id from
T join
(SELECT
min(log_cre_date) mindt,
t.object_id
FROM
t
GROUP BY
t.object_id) t1
On t.object_id = t1.object_id
And t.log_cre_date = t1.mindt;
干杯!
答案 2 :(得分:0)
也许此查询将运行得更快:
select object_id, id
from (
select object_id, first_value(id) over(partition by object_id order by log_cre_date) as id
from t
)
group by object_id, id;
希望有帮助!