다른 테이블의 필드에서 한 테이블의 SQL 업데이트 필드
두 개의 테이블이 있습니다.
A [ID, column1, column2, column3]
B [ID, column1, column2, column3, column4]
A
항상 하위 집합 될 것이다 B
(의 모든 열을 의미 A
도있다 B
).
나는 특정과 기록을 업데이트 할 ID
에서 B
의 데이터와 A
모든 열에 대한 A
. 이 ID
모두 존재 A
하고 B
.
거기 UPDATE
구문이나, 단지 말을 열 이름을 지정하지 않고 그렇게 할 수있는 다른 방법 "A의 모든 열을 설정은" ?
PostgreSQL을 사용하고 있으므로 특정 비표준 명령도 허용됩니다 (그러나 바람직하지는 않습니다).
비표준 FROM 절을 사용할 수 있습니다 .
UPDATE b
SET column1 = a.column1,
column2 = a.column2,
column3 = a.column3
FROM a
WHERE a.id = b.id
AND b.id = 1
그 질문은 오래되었지만 가장 좋은 대답은 아직 얻지 못했다고 느꼈습니다.
거기
UPDATE
구문 ... 열 이름을 지정하지 않고는 ?
동적 SQL을 사용한 일반 솔루션
결합 할 고유 한 열을 제외하고 ( id
예에서) 열 이름을 알 필요가 없습니다 . 내가 생각할 수있는 모든 코너 케이스에 안정적으로 작동합니다.
이것은 PostgreSQL에만 해당됩니다. 나는 information_schema , 특히 테이블을 기반으로 동적 코드를 작성하고 있습니다. 이 테이블 information_schema.columns
은 ISO SQL 표준에 정의되어 있으며 가장 현대적인 RDBMS (Oracle 제외)가 지원합니다. 그러나 동적 SQL을 실행하는 PL / pgSQL 코드 가 포함 된 DO
명령문 은 완전히 표준이 아닌 PostgreSQL 구문입니다.
DO
$do$
BEGIN
EXECUTE (
SELECT
'UPDATE b
SET (' || string_agg(quote_ident(column_name), ',') || ')
= (' || string_agg('a.' || quote_ident(column_name), ',') || ')
FROM a
WHERE b.id = 123
AND a.id = b.id'
FROM information_schema.columns
WHERE table_name = 'a' -- table name, case sensitive
AND table_schema = 'public' -- schema name, case sensitive
AND column_name <> 'id' -- all columns except id
);
END
$do$;
의 모든 열에 b
대해 일치하는 열을 가정 하지만 다른 방법은 아닙니다. 추가 열이있을 수 있습니다.a
b
WHERE b.id = 123
선택한 행만 업데이트하려면 선택 사항입니다.
자세한 설명과 관련된 답변 :
일반 SQL을 사용한 부분 솔루션
공유 열 목록
여전히 두 테이블이 공유하는 열 이름 목록을 알아야합니다. 여러 열을 업데이트하기위한 구문 바로 가기-다른 답변이 지금까지 제안 된 것보다 짧습니다.
UPDATE b
SET ( column1, column2, column3)
= (a.column1, a.column2, a.column3)
FROM a
WHERE b.id = 123 -- optional, to update only selected row
AND a.id = b.id;
이 구문은 2006 년 12 월에 Postgres 8.2에서 도입되었습니다. dba.SE 의 매뉴얼 및 관련 답변에 대한
자세한 내용 :
With list of columns in B
If all columns of A
are defined NOT NULL
(but not necessarily B
),
and you know the column names of B
(but not necessarily A
).
UPDATE b
SET (column1, column2, column3, column4)
= (COALESCE(ab.column1, b.column1)
, COALESCE(ab.column2, b.column2)
, COALESCE(ab.column3, b.column3)
, COALESCE(ab.column4, b.column4)
)
FROM (
SELECT *
FROM a
NATURAL LEFT JOIN b -- append missing columns
WHERE b.id IS NULL -- only if anything actually changes
AND a.id = 123 -- optional, to update only selected row
) ab
WHERE b.id = ab.id;
The NATURAL LEFT JOIN
joins a row from b
where all columns of the same name hold same values. We don't need an update in this case (nothing changes) and can eliminate those rows early in the process (WHERE b.id IS NULL
).
We still need to find a matching row, so b.id = ab.id
in the outer query.
db<>fiddle here
Old sqlfiddle.
This is standard SQL except for the FROM
clause.
It works no matter which of the columns are actually present in A
, but the query cannot distinguish between actual NULL values and missing columns in A
, so it is only reliable if all columns in A
are defined NOT NULL
.
There are multiple possible variations, depending on what you know about both tables.
I have been working with IBM DB2 database for more then decade and now trying to learn PostgreSQL.
It works on PostgreSQL 9.3.4, but does not work on DB2 10.5:
UPDATE B SET
COLUMN1 = A.COLUMN1,
COLUMN2 = A.COLUMN2,
COLUMN3 = A.COLUMN3
FROM A
WHERE A.ID = B.ID
Note: Main problem is FROM cause that is not supported in DB2 and also not in ANSI SQL.
It works on DB2 10.5, but does NOT work on PostgreSQL 9.3.4:
UPDATE B SET
(COLUMN1, COLUMN2, COLUMN3) =
(SELECT COLUMN1, COLUMN2, COLUMN3 FROM A WHERE ID = B.ID)
FINALLY! It works on both PostgreSQL 9.3.4 and DB2 10.5:
UPDATE B SET
COLUMN1 = (SELECT COLUMN1 FROM A WHERE ID = B.ID),
COLUMN2 = (SELECT COLUMN2 FROM A WHERE ID = B.ID),
COLUMN3 = (SELECT COLUMN3 FROM A WHERE ID = B.ID)
This is a great help. The code
UPDATE tbl_b b
SET ( column1, column2, column3)
= (a.column1, a.column2, a.column3)
FROM tbl_a a
WHERE b.id = 1
AND a.id = b.id;
works perfectly.
noted that you need a bracket "" in
From "tbl_a" a
to make it work.
Not necessarily what you asked, but maybe using postgres inheritance might help?
CREATE TABLE A (
ID int,
column1 text,
column2 text,
column3 text
);
CREATE TABLE B (
column4 text
) INHERITS (A);
This avoids the need to update B.
But be sure to read all the details.
Otherwise, what you ask for is not considered a good practice - dynamic stuff such as views with SELECT * ...
are discouraged (as such slight convenience might break more things than help things), and what you ask for would be equivalent for the UPDATE ... SET
command.
you can build and execute dynamic sql to do this, but its really not ideal
Try Following
Update A a, B b, SET a.column1=b.column1 where b.id=1
EDITED:- Update more than one column
Update A a, B b, SET a.column1=b.column1, a.column2=b.column2 where b.id=1
'IT박스' 카테고리의 다른 글
Vim에서 HTML 태그를 어떻게 빨리 닫을 수 있습니까? (0) | 2020.07.28 |
---|---|
CRON이 올바른 경로를 호출하도록하는 방법 (0) | 2020.07.28 |
두 파일을 한 줄씩 비교하고 다른 파일에서 차이를 생성 (0) | 2020.07.28 |
이미 존재하고 어쨌든 보호 된 리눅스에서 파일을 비우는 방법 (“잘라 내기”)은 무엇입니까? (0) | 2020.07.28 |
처음 세 열을 제외하고 모두 인쇄 (0) | 2020.07.28 |