두 개의 테이블이 있습니다.
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
SQL 표준에 정의되어 있고 대부분의 주요 RDBMS (Oracle 제외)에 정의 된 table을 기반으로 동적 코드를 작성 하고 있습니다. 그러나 동적 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 년에 Postgres 8.2에서 도입되었습니다. 설명서의 세부 사항.
관련 :
열 목록 포함 B
경우 의 모든 열이 A
정의된다 NOT NULL
(반드시 그런 것은 아니지만 B
),
그리고 당신이 알고있는 의 열 이름을 B
(그러나 반드시 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;
은 NATURAL LEFT JOIN
에서 행 조인 b
같은 이름의 모든 열을 같은 값을 유지 어디에. 이 경우 업데이트가 필요하지 않으며 (변경 사항 없음) 프로세스 초기에 해당 행을 제거 할 수 있습니다 ( WHERE b.id IS NULL
).
여전히 일치하는 행을 찾아야하므로 b.id = ab.id
외부 쿼리에서.
db <> 여기에 바이올린
Old sqlfiddle.
이것은 절을 제외하고FROM
표준 SQL 입니다.
실제로 존재하는 열에 관계없이 작동 A
하지만 쿼리는 실제 NULL 값과 누락 된 열을 구분할 수 없으므로의 A
모든 열 A
이 정의 된 경우에만 신뢰할 수 NOT NULL
있습니다.
두 테이블에 대해 알고있는 내용 에 따라 여러 가지 가능한 변형이 있습니다.
답변
저는 10 년 이상 IBM DB2 데이터베이스로 작업 해 왔으며 이제 PostgreSQL을 배우려고 노력하고 있습니다.
PostgreSQL 9.3.4에서는 작동하지만 DB2 10.5에서는 작동하지 않습니다.
UPDATE B SET
COLUMN1 = A.COLUMN1,
COLUMN2 = A.COLUMN2,
COLUMN3 = A.COLUMN3
FROM A
WHERE A.ID = B.ID
참고 : 주요 문제점은 DB2에서 지원되지 않고 ANSI SQL에서도 지원되지 않는 FROM 원인입니다.
DB2 10.5에서는 작동하지만 PostgreSQL 9.3.4에서는 작동하지 않습니다.
UPDATE B SET
(COLUMN1, COLUMN2, COLUMN3) =
(SELECT COLUMN1, COLUMN2, COLUMN3 FROM A WHERE ID = B.ID)
드디어! PostgreSQL 9.3.4 및 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)
답변
이것은 큰 도움이됩니다. 코드
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;
완벽하게 작동합니다.
에 대괄호 “”가 필요하다고 언급했습니다.
From "tbl_a" a
작동합니다.
답변
반드시 요청한 것은 아니지만 postgres 상속을 사용하면 도움이 될 수 있습니까?
CREATE TABLE A (
ID int,
column1 text,
column2 text,
column3 text
);
CREATE TABLE B (
column4 text
) INHERITS (A);
이렇게하면 B를 업데이트 할 필요가 없습니다.
그러나 모든 세부 사항 을 읽으십시오 .
그렇지 않으면, 당신이 요구하는 것은 좋은 관행으로 간주되지 않습니다.보기와 같은 동적 인 것들은 SELECT * ...
권장되지 않습니다. (그런 약간의 편리함은 도움이되는 것보다 더 많은 것을 망칠 수 있기 때문입니다) 그리고 당신이 요청하는 것은 UPDATE ... SET
명령에 대해 동등 할 것 입니다.
답변
이를 위해 동적 SQL을 빌드하고 실행할 수 있지만 실제로는 이상적이지 않습니다.
답변
팔로우하기
Update A a, B b, SET a.column1=b.column1 where b.id=1
수정 됨 :-둘 이상의 열 업데이트
Update A a, B b, SET a.column1=b.column1, a.column2=b.column2 where b.id=1