IT박스

다른 테이블의 필드에서 한 테이블의 SQL 업데이트 필드

itboxs 2020. 7. 28. 08:16
반응형

다른 테이블의 필드에서 한 테이블의 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대해 일치하는 열을 가정 하지만 다른 방법은 아닙니다. 추가 열이있을 수 있습니다.ab

WHERE b.id = 123 선택한 행만 업데이트하려면 선택 사항입니다.

SQL 바이올린.

자세한 설명과 관련된 답변 :

일반 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;

SQL 바이올린.

이 구문은 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

참고URL : https://stackoverflow.com/questions/2763817/sql-update-fields-of-one-table-from-fields-of-another-one

반응형