Jede Lösung, die aktuelle Tabellenwerte überprüft, funktioniert nicht in einer "echten" Umgebung mit mehreren Benutzern und mehreren Sitzungen und parallelen Transaktionen.
Ich glaube, Sie brauchen, um die zwei Anforderungen zu trennen:
- die Fähigkeit haben, Aufzeichnungen auf sequenzieren basiert, wenn sie erstellt wurden
- die Fähigkeit haben, auf Rekord-Sequenzierung innerhalb eines Jahres zu berichten.
Die erste wird mit einer Sequenz behandelt, da diese hierfür genau gestaltet und Concurrency (mehrere Benutzer, mehrere Transaktionen, ...) behandeln.
Die zweite ist eine Berichtspflicht und bietet abhängig von den Leistungsanforderungen eine Reihe von Optionen.
Zu allererst eine Sequenz erzeugen:
create sequence seq_analysis_id start with 1 increment by 1 nocache nocycle;
Nicht mal eine Basistabelle erstellen und einen Trigger, um das Auto-Inkrement zu handhaben:
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
Ok - so dass alles gut funktioniert, aber doesn ‚t Ihnen, was Sie für :)
gefragt Dies ist der zweite Teil - die Meldepflicht:
Die erste Option ist nur die Zahlen erhalten müssen Sie dynamisch:
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;
Verwendung von analytischen Funktionen (row_number
in diesem Fall) sind eine gute Möglichkeit, diese Art der Sache zu behandeln.
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
Ich habe von analysis_date, analysis_id
in der row_number
Funktion bestellt.Dies ist wahrscheinlich nicht notwendig, aber würde benötigt werden, wenn Sie mit Updates für die analysis_date
umgehen müssten (in diesem Fall funktioniert die Sequenz nicht mehr für die Bestellung innerhalb eines Jahres allein).
Man könnte dies ein wenig einfacher für die Berichterstattung machen, indem es in einer Ansicht Verpackung:
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;
Dies alles was Sie brauchen können, aber wenn Sie große Datenmengen haben, dann können Sie im Voraus berechnen müssen einige dieser Werte. Sie haben virtuelle Spalten in 11g, aber diese funktionieren nicht für analytische Funktionen. Meine Wahl wäre hier eine materialisierte Ansicht verwenden - viele Möglichkeiten, materialisierte Ansicht Auffrischungen zu handhaben und die einfachste wäre:
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
In diesem Fall wird die materialisierte Ansicht würde manuell aktualisiert:
exec dbms_mview.refresh('analysis_data_mv');
Hoffe das hilft.
Möchten Sie die gleiche Zeile der Tabelle aktualisieren, die mit einem Spaltenwert eingefügt wird 1 – XING
Nein, dass die Spalte nicht aktualisiert wird – SantyEssac