programing

Postgre의 계산된/계산된/가상/파생 열SQL

muds 2023. 5. 16. 23:12
반응형

Postgre의 계산된/계산된/가상/파생 열SQL

Postgre를 합니까?SQL은 MS SQL Server와 같이 계산/계산된 열을 지원합니까?문서에서 아무것도 찾을 수 없지만, 이 기능이 다른 많은 DBMS에 포함되어 있기 때문에 뭔가 누락된 것이 있을 수 있다고 생각했습니다.

예: http://msdn.microsoft.com/en-us/library/ms191250.aspx

포스트그레스 12 이상

STORED 생성된 열은 SQL 표준에 정의되어 있고 DB2, MySQL 및 Oracle을 포함한 일부 RDBMS에 의해 구현된 Postgres 12와 함께 도입되었습니다.또는 SQL Server의 "계산된 열"과 유사합니다.

간단한 예:

CREATE TABLE tbl (
  int1    int
, int2    int
, product bigint GENERATED ALWAYS AS (int1 * int2) STORED
);

만지작거리다

VIRTUAL생성된 열은 다음 반복 중 하나와 함께 제공될 수 있습니다.(아직 Postgres 15에는 없음).

관련:

포스트그레스 11 이상

Postgres 11까지의 "생성된 열"은 지원되지 않습니다.
에뮬레이트할 수 있습니다.VIRTUAL속성 표기법()을 사용하여 함수를 사용하여 생성된 열tbl.col가상으로 생성된 열처럼 보이고 작동합니다.그것은 역사적인 이유로 Postgres에 존재하는 약간의 구문 이상한 것이고 우연히 그 경우에 들어맞습니다.이 관련 답변에는 코드 예제가 있습니다.

) 은 (으)ㄹ 수 없는 것 요.SELECT * FROM tbl 래도그.항상 명시적으로 나열해야 합니다.

함수가 다음과 같은 경우 일치하는 식 인덱스로도 지원할 수 있습니다.IMMUTABLE 예:

CREATE FUNCTION col(tbl) ... AS ...  -- your computed expression here
CREATE INDEX ON tbl(col(tbl));

대안

또는 식 인덱스와 선택적으로 결합된 를 사용하여 유사한 기능을 구현할 수 있습니다.그리고나서SELECT *생성된 열을 포함할 수 있습니다.

("지속"(속")STORED) 계산된 열은 기능적으로 동등한 방식으로 트리거를 사용하여 구현할 수 있습니다.

구체화된 보기는 Postgres 9.3 이후 구현된 관련 개념입니다.
이전 버전에서는 MV를 수동으로 관리할 수 있습니다.

네 할 수 있어요!!해결책은 쉽고 안전하며 성능이 뛰어나야 합니다.

postgresql은 처음이지만 와 쌍을 이루는 인덱스를 사용하여 계산된 열을 만들 수 있는 것 같습니다(뷰는 선택 사항이지만 삶을 좀 더 쉽게 만듭니다).

이 내계이라고 합니다.md5(some_string_field)그런 다음 인덱스를 다음과 같이 만듭니다.

CREATE INDEX some_string_field_md5_index ON some_table(MD5(some_string_field));

이제, 다음과 같은 작업을 수행하는 모든 쿼리MD5(some_string_field)처음부터 계산하는 대신 인덱스를 사용합니다.예:

SELECT MAX(some_field) FROM some_table GROUP BY MD5(some_string_field);

이것은 설명과 함께 확인할 수 있습니다.

그러나 이 시점에서 열을 구성하는 정확한 방법을 알고 있는 테이블 사용자에게 의존하고 있습니다.삶을 더 쉽게 만들기 위해, 당신은 다음을 만들 수 있습니다.VIEW계산된 값을 새 열로 추가하여 원래 테이블의 확장 버전에 추가합니다.

CREATE VIEW some_table_augmented AS 
   SELECT *, MD5(some_string_field) as some_string_field_md5 from some_table;

이제 다음을 사용하는 모든 쿼리some_table_augmented할 수 .some_string_field_md5그것이 어떻게 작동하는지에 대해 걱정하지 않고.그들은 단지 좋은 성과를 얻을 뿐입니다.보기는 원래 테이블의 데이터를 복사하지 않으므로 메모리 측면에서뿐만 아니라 성능 측면에서도 좋습니다.그러나 원본 테이블에만 업데이트/삽입할 수는 없지만, 정말로 원한다면 규칙을 사용하여 삽입 및 업데이트를 원본 테이블로 리디렉션할 수 있다고 생각합니다(마지막 점은 제가 직접 시도해 본 적이 없기 때문에 틀릴 수 있습니다).

편집: 쿼리에 경쟁하는 인덱스가 포함된 경우 플래너 엔진에서 식을 전혀 사용하지 않을 수 있습니다.선택은 데이터에 따라 다릅니다.

이것을 하는 한 가지 방법은 방아쇠를 이용하는 것입니다!

CREATE TABLE computed(
    one SERIAL,
    two INT NOT NULL
);

CREATE OR REPLACE FUNCTION computed_two_trg()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
AS $BODY$
BEGIN
    NEW.two = NEW.one * 2;

    RETURN NEW;
END
$BODY$;

CREATE TRIGGER computed_500
BEFORE INSERT OR UPDATE
ON computed
FOR EACH ROW
EXECUTE PROCEDURE computed_two_trg();

행이 업데이트되거나 삽입되기 전에 트리거가 실행됩니다.하고자 하는 .NEW기록한 다음 해당 기록을 반환합니다.

PostgreSQL 12는 생성된 열을 지원합니다.

PostgreSQL 12 베타 1 출시!

생성된 열

PostgreSQL 12에서는 다른 열의 내용을 사용하여 식을 사용하여 값을 계산하는 생성된 열을 생성할 수 있습니다. 이 기능은 저장된 생성된 열을 제공하며, 이 열은 삽입 및 업데이트에 계산되고 디스크에 저장됩니다.열을 쿼리의 일부로 읽을 때만 계산되는 가상 생성 열은 아직 구현되지 않았습니다.


생성된 열

생성된 열은 항상 다른 열에서 계산되는 특수 열입니다.따라서 보기가 테이블에 해당하는 것은 열에 해당합니다.

CREATE TABLE people (
    ...,
    height_cm numeric,
    height_in numeric GENERATED ALWAYS AS (height_cm * 2.54) STORED
);

db<>디플 데모

글쎄요, 이것이 당신이 의미하는 것인지 확실하지 않지만 Posgres는 일반적으로 "dummy" ETL 구문을 지원합니다.표에 빈 열 하나를 만든 다음 행의 값에 따라 계산된 레코드로 채워야 했습니다.

UPDATE table01
SET column03 = column01*column02; /*e.g. for multiplication of 2 values*/
  1. 너무 멍청해서 당신이 찾고 있는 것이 아닌 것 같습니다.
  2. 분명히 그것은 역동적이지 않습니다, 당신은 그것을 한 번 실행합니다.하지만 방아쇠를 당길 수 있는 장애물은 없습니다.

빈 가상 열 생성 예제

,(SELECT *
  From (values (''))
  A("virtual_col"))

값이 있는 두 개의 가상 열 생성 예제

SELECT *
From (values (45,'Completed')
    , (1,'In Progress')
    , (1,'Waiting')
    , (1,'Loading')
   ) A("Count","Status")
order by "Count" desc

계산된 용어를 사용하는 코드가 있습니다. 포스트에 없습니다.PADB에서 실행되는 SQL 순수 데이터

사용 방법은 다음과 같습니다.

create table some_table as
    select  category, 
            txn_type,
            indiv_id, 
            accum_trip_flag,
            max(first_true_origin) as true_origin,
            max(first_true_dest ) as true_destination,
            max(id) as id,
            count(id) as tkts_cnt,
            (case when calculated tkts_cnt=1 then 1 else 0 end) as one_way
    from some_rando_table
    group by 1,2,3,4    ;

Check 제약 조건이 있는 경량 솔루션:

CREATE TABLE example (
    discriminator INTEGER DEFAULT 0 NOT NULL CHECK (discriminator = 0)
);

언급URL : https://stackoverflow.com/questions/8250389/computed-calculated-virtual-derived-columns-in-postgresql

반응형