任何查看当前表值的解决方案都不适用于包含多个用户和多个会话以及并行事务的“真实”环境。
我认为你需要分离出两个要求:
- 不得不基于序列的时候被创建
- 不得不在一年内记录排序报告的能力上记录的能力。
首先是使用序列因为这些正是为此设计和处理并发(多用户,多笔交易,...)来处理。
第二个是报告要求,根据性能要求有多个选项。
首先创建一个序列:
create sequence seq_analysis_id start with 1 increment by 1 nocache nocycle;
不是让我们创建一个基表和触发器来处理自动递增:
create table analysis_data (
analysis_id integer not null,
analysis_date date not null
);
alter table analysis_data add constraint pk_analysis_data primary key (analysis_id);
create or replace trigger trg_analysis_data
before insert on analysis_data
for each row
begin
:new.analysis_id := seq_analysis_id.nextval();
end trg_analysis_data;
/
insert into analysis_data (analysis_date) values (to_date('2015-12-28', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2015-12-29', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2015-12-30', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2015-12-31', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2016-01-01', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2016-01-02', 'YYYY-MM-DD'));
insert into analysis_data (analysis_date) values (to_date('2016-01-03', 'YYYY-MM-DD'));
commit;
select * from analysis_data;
ANALYSIS_ID ANALYSIS_DATE
1 28/12/2015
2 29/12/2015
3 30/12/2015
4 31/12/2015
5 01/01/2016
6 02/01/2016
7 03/01/2016
好 - 让所有工作正常,但没有按给你所要求的:)
这是第二部分 - 报告要求:
第一个选项是刚拿到号码,你需要动态:
select
analysis_id,
analysis_date,
extract(year from analysis_date) analysis_year,
row_number()
over (partition by trunc(analysis_date, 'YYYY')
order by analysis_date, analysis_id) analysis_number
from
analysis_data;
使用解析函数(row_number
在这种情况下)是处理这种事情的好方法。
ANALYSIS_ID ANALYSIS_DATE ANALYSIS_YEAR ANALYSIS_NUMBER
1 28/12/2015 2015 1
2 29/12/2015 2015 2
3 30/12/2015 2015 3
4 31/12/2015 2015 4
5 01/01/2016 2016 1
6 02/01/2016 2016 2
7 03/01/2016 2016 3
我已在row_number
函数中订购analysis_date, analysis_id
。这可能不是必需的,但如果您必须处理analysis_date
的更新(在这种情况下,序列不再适用于年内订购),则可能需要此选项。
您可以通过在视图中包装它使本作的报告有点更直截了当:
create or replace view analysis_data_v as
select
analysis_id,
analysis_date,
extract(year from analysis_date) analysis_year,
row_number()
over (partition by trunc(analysis_date, 'YYYY')
order by analysis_date, analysis_id) analysis_number
from
analysis_data;
这可能是你所需要的,但如果你有大量的数据集,那么你可能需要预先计算其中一些价值。您有11g中的虚拟列,但这些不适用于分析功能。在这里,我的选择是使用物化视图 - 很多方法来处理物化视图刷新,最简单的是:
create materialized view analysis_data_mv
build immediate
refresh complete on demand
as
select
analysis_id,
analysis_date,
analysis_year,
analysis_number
from
analysis_data_v;
select * from analysis_data_mv order by analysis_year, analysis_number;
ANALYSIS_ID ANALYSIS_DATE ANALYSIS_YEAR ANALYSIS_NUMBER
1 28/12/2015 2015 1
2 29/12/2015 2015 2
3 30/12/2015 2015 3
4 31/12/2015 2015 4
5 01/01/2016 2016 1
6 02/01/2016 2016 2
7 03/01/2016 2016 3
在这种情况下,物化视图就可以手动刷新:
exec dbms_mview.refresh('analysis_data_mv');
希望这可以帮助。
是否要更新以列值插入的表中的同一行1 – XING
否该列不会更新 – SantyEssac