PostgreSQL의 WITH .. AS .. 절 대안

메멧

다음 유형의 몇 가지 큰 쿼리가 있습니다 (명확성을 위해 단순화 됨).

create function myfunction()
  returns void
as $$
begin

...
with t as (
  total                 as total,
  total * 100 / total   as total_percent,
  total / people.count  as total_per_person,
  part1                 as part1,
  part1 * 100 / total   as part1_percent,
  part1 / people.count  as part1_per_person,
  part2                 as part2,
  part2 * 100 / total   as part2_percent,
  part2 / people.count  as part2_per_person,
  ...
  from (
    select
    total.amount as total
    part1.amount as part1
    part2.amount as part2
    ...
    people.amount as people
    from (select ...from mytable..) total
    left join (select ...from mytable..) part1 on ...
    left join (select ...from mytable..) part2 on ...
    ...
    left join (select ...from mytable..) people on ...
  ) r
)

insert into another_table  -- << NOW I NEED TO REPLACE THIS WITH "RETURN QUERY"
        select .., total             from t
  union select .., total_percent     from t
  union select .., total_per_person  from t
  union select .., part1             from t
  union select .., part1_percent     from t
  union select .., part1_per_person  from t
  union select .., part2             from t
  union select .., part2_percent     from t
  union select .., part2_per_person  from t
  ...

...
$$ language plpgsql;

너무 큰 이유는 대부분의 열이 다른 열에서 파생되기 때문입니다. 쿼리는 데이터를 가져오고 집계 할 때 반복을 최소화하여 런타임을 최소화하도록 설계되었습니다 ( mytable행이 400 만 개 미만 이므로이 쿼리를 실행하는 데 약 10 초가 걸리기 때문입니다 ). 통합 연산자와 결합 된 another_table에 15 개의 열이 모두 삽입됩니다.

with .. as ..절은이 시나리오에서 완벽하게 작동했습니다. 그러나 이제 프로그램을 리팩토링하면서 생성 된 데이터 세트를 사후 처리를 위해 다른 함수에 전달해야합니다 (other_table에 삽입하는 대신).

그래서, 나는 대체했다 insert into another_table과를 return query하지만 WITH .. AS ..그렇게하지 않았다.

즉, 여기에 내가 도달하려는 업데이트 된 기능이 있습니다 (작동하지 않음-인터프리터가 블록 return query이후에 예상하지 않음 with .. as).

create function myfunction()
  returns setof data -- << now returning a data set
as $$
begin

...
with t as (
  --SAME QUERY
  ) r
)

return query  -- << line that is changed
    -- SAME SELECT HERE
...
$$ language plpgsql;

이제 내 질문은 대체 무엇 WITH .. AS ..입니까? 그래서 나는 return query그것과 함께 사용할 수 있습니다 . 임시 테이블을 사용해 볼 계획이지만 .NET으로 작성된 쿼리를 어떻게 다시 작성할 수 있는지 궁금합니다 with .. as ....

Erwin Brandstetter

질문의 쿼리에는 몇 가지 명백한 넌센스 부분이 있습니다. 이전에 실행 했으므로 수동 단순화의 아티팩트라고 가정합니까?
처럼 : 그것은 단지 . 또는 : 조인 조건이없는 조인, 일반 구문 오류입니다. total * 100 / total 100

그 외에는 RETURN QUERYSQL이 아니라 plpgsql 명령입니다.

plpgsql 코드와 함께 function또는 DO문을 사용하고 있음을 언급하지 않았 거나 SQL에 잘못된 구문을 사용하려고합니다.

plpgsql 에서는 SQL 쿼리 RETURN QUERY 앞에 CTE (Common Table Expression) 를 넣으면 작동합니다 (명백한 구문 오류는 제쳐두고) . CTE (Common Table Expression)WITH절의 표준 이름 입니다. SQL 문의 일부입니다 .

RETURN QUERY        -- plpgsql command
WITH  t AS ( ... )  -- here starts the SQL query
SELECT .., total                 FROM t
UNION SELECT .., total_percent   FROM t
UNION SELECT.., total_per_person FROM t
-- etc.

그것에있는 동안, 그 마지막 부분은 아마도 가장 잘못 되었을 입니다. 나는 당신이 원하는 것을 확신 하지만 결과에서 중복을 접을 수는 UNION ALL없습니다 UNION.

더 좋은 방법 VALUESLATERAL조인 에서 표현식 과 함께이 스마트 기술을 사용 하여 긴 행을 "반대 피벗"하는 것입니다.

...
SELECT t1.*
FROM   t, LATERAL (
   VALUES
       (.., t.total)   -- whatever you may be hiding behind ".."
     , (.., t.total_percent)
     , (.., t.total_per_person)
     , (.., t.part1)
     , (.., t.part1_percent)
       -- etc.
   ) t1 ("name_for ..", total);

상당히 짧고 저렴해야합니다. dba.SE의 관련 답변에서 @Andriy에 대한 아이디어에 대한 크레딧

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

MySQL의 MINUS 절의 대안?

분류에서Dev

Where Exist 절 MySQL의 대안

분류에서Dev

Mysql의 UNION 절 대안

분류에서Dev

NOT IN 절이있는 Hive 쿼리의 대안

분류에서Dev

"order by"절의 다른 동작 : Oracle 대 PostgreSQL

분류에서Dev

postgresql의 NOT IN 절

분류에서Dev

사파리의 절대 위치에 대한 대안?

분류에서Dev

제품 필터에 대한 WHERE IN 절의 대안

분류에서Dev

절대 div 안에있는 요소의 수평 중심?

분류에서Dev

Django, DRF 및 PostgreSQL의 시간대 적절한 설정

분류에서Dev

CSS의 상대 vs 절대

분류에서Dev

GF의 상대 절 (which)

분류에서Dev

INT_MIN의 절대 값

분류에서Dev

옥의 절대 링크

분류에서Dev

Python의 절대 링크

분류에서Dev

fopen ()의 절대 경로

분류에서Dev

IFC의 절대 벽 위치

분류에서Dev

PUG의 절대 경로

분류에서Dev

Spring Boot의 절대 경로

분류에서Dev

PostgreSQL-select 문의 if 절

분류에서Dev

IN 절이 입력 될 때 대체 값 (postgreSQL)

분류에서Dev

엔티티의 기본값을 사용하여 PostgreSQL로 최대 절전 모드

분류에서Dev

postgresql의 테이블에 대한 FROM 절 항목이 없습니다.

분류에서Dev

다음과 같은 Ms-sql의 저장된 절차에 대한 Mysql의 'Stuff'및 'FOR XML PATH'대안

분류에서Dev

CYGWIN의 절대 및 상대 경로

분류에서Dev

jquery의 절대 및 상대 경로

분류에서Dev

메뉴의 절대 및 상대 위치

분류에서Dev

메뉴의 절대 및 상대 위치

분류에서Dev

Xamarin의 절대 레이아웃 대 Relativelayout