Załóżmy, że mam tabelę z 10 rekordami / krotkami. Teraz chcę zaktualizować atrybut 6. rekordu z tym samym atrybutem pierwszego rekordu, 2.-7., 3.-8., 4.-9., 5-10-tego w kroku, tzn. Bez użycia kursora / pętli. Dowolna liczba tabel tymczasowych jest dozwolona. Jaka jest strategia, aby to zrobić?
Odpowiedzi:
0 dla odpowiedzi № 1PostgreSQL (i prawdopodobnie inne RDBMS) pozwalają ci używać self-joinów UPDATE
oświadczenia, tak jak możesz SELECT
sprawozdania:
UPDATE tbl
SET attr = t2.attr
FROM tbl t2
WHERE tbl.id = t2.id + 5
AND tbl.id >= 6
0 dla odpowiedzi nr 2
Byłoby to łatwe dzięki aktualizacji z połączeniem, aleOracle tego nie robi, a najbliższy substytut może być bardzo trudny, aby dostać się do pracy.To jest najłatwiejszy sposób.Obejmuje to podzapytanie, aby uzyskać nową wartość i skorelowane podzapytanie w where
klauzula. Wygląda na skomplikowaną, ale set
podzapytanie powinno być zrozumiałe.
The where
podzapytanie ma tylko jeden cel: łączy dwie tabele, podobnie jak on
byłoby zrobić, gdybyśmy mogli dołączyć. Z wyjątkiem pola używanego z głównej tabeli (tej, która jest aktualizowana) musi być kluczowym polem. Jak się okazuje, przy wykonywaniu "połączenia" poniżej, są one tym samym polem, ale jest to wymagane.
Dodaj do where
klauzuli innych kryteriów krępowania, jak pokazano.
update Tuples t1
set t1.Attr =(
select t2.Attr
from Tuples t2
where t2.Attr = t1.Attr - 5 )
where exists(
select t2.KeyVal
from Tuples t2
where t1.KeyVal = t2.KeyVal)
and t1.Attr > 5;
SqlFiddle wyciąga teraz hissy fit, więc tutaj dane:
create table Tuples(
KeyVal int not null primary key,
Attr int
);
insert into Tuples
select 1, 1 from dual union all
select 2, 2 from dual union all
select 3, 3 from dual union all
select 4, 4 from dual union all
select 5, 5 from dual union all
select 6, 6 from dual union all
select 7, 7 from dual union all
select 8, 8 from dual union all
select 9, 9 from dual union all
select 10, 10 from dual;
Tabela zaczyna wyglądać tak:
KEYVAL ATTR
------ ----
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
z tym wynikiem:
KEYVAL ATTR
------ ----
1 1
2 2
3 3
4 4
5 5
6 1
7 2
8 3
9 4
10 5