7.8. with스포츠 토토 사이트 (공통 테이블 표현)#

with더 큰 스포츠 토토 사이트에서 사용하기 위해 보조 문을 작성하는 방법을 제공합니다. 이 진술은 종종 일반적인 테이블 표현 또는이라고합니다.CTEs, 하나의 스포츠 토토 사이트에만 존재하는 임시 테이블을 정의하는 것으로 생각할 수 있습니다. a의 각 보조 문장with절은 A가 될 수 있습니다.select, 삽입, 업데이트, 삭제또는병합; 그리고with절 자체는 A 일 수있는 기본 설명에 첨부됩니다.select, 삽입, 업데이트, 삭제또는병합.

7.8.1. selectinwith #

기본 값selectinwith복잡한 쿼리를 더 간단한 부품으로 분해하는 것입니다. 예는 다음과 같습니다.

greal_sales as (
    Total_sales로 영역, 합 (금액)을 선택하십시오
    주문에서
    지역별 그룹
), top_regions as (
    지역을 선택하십시오
    regional_sales에서
    여기서 total_sales (select sum (total_sales)/regional_sales에서 10)
))
지역 선택,
       제품,
       sum (수량)으로 product_units,
       sum (금액)은 product_sales입니다
주문에서
지역 (Top_regions에서 지역 선택)
지역별 그룹, 제품;

상위 판매 지역에서만 제품 별 판매량을 표시합니다. 그만큼with절의 조항은Regional_salesandTOP_REGIONSRegional_salesTOP_REGIONS그리고의 출력TOP_REGIONS기본에서 사용됩니다select스포츠 토토 사이트. 이 예는없이 쓰여졌을 수 있습니다.with, 그러나 우리는 두 가지 레벨의 중첩 하위가 필요했을 것입니다selects. 이런 식으로 따르는 것이 조금 더 쉽습니다.

7.8.2. 재귀 쿼리#

선택 사항재귀수정 자 변경with단순한 구문 편의에서 표준 SQL에서 불가능한 것을 달성하는 기능으로. 사용재귀, awith스포츠 토토 사이트는 자체 출력을 참조 할 수 있습니다. 매우 간단한 예는 1 ~ 100의 정수를 합산하는이 스포츠 토토 사이트입니다.

재귀 t (n) as (
    값 (1)
  모두
    n <100에서 n+1을 선택하십시오
))
t;에서 합 (n)을 선택하십시오.

재귀의 일반적인 형태with스포츠 토토 사이트는 항상입니다.비 수거 용어,Union(또는Union All), A재귀 용어, 여기서 재귀 용어 만 쿼리의 자체 출력에 대한 참조를 포함 할 수 있습니다. 이러한 스포츠 토토 사이트는 다음과 같이 실행됩니다.

재귀 쿼리 평가

  1. 회수 기간을 평가합니다. 을 위한Union(하지만Union All), 중복 행을 버립니다. 재귀 쿼리 결과에 남은 모든 행을 포함시키고 임시로 배치하십시오작업대.

  2. 작업 테이블이 비어 있지 않은 한 다음 단계를 반복하십시오.

    1. 재귀 적 자기 참조를 위해 작업대의 현재 내용을 대체하여 재귀 용어를 평가합니다. 을 위한Union(하지만Union All), 이전 결과 행을 복제하는 중복 행과 행을 버립니다. 재귀 쿼리 결과에 남은 모든 행을 포함시키고 임시로 배치하십시오중간 표.

    2. 작업대의 내용을 중간 테이블의 내용으로 교체 한 다음 중간 테이블을 비우십시오.

Note

while재귀쿼리를 재귀 적으로 지정할 수있게되며, 내부적으로 이러한 스포츠 토토 사이트는 반복적으로 평가됩니다.

위의 예에서 작업 테이블은 각 단계에서 단일 행을 가지고 있으며 연속 단계에서 1에서 100까지의 값을 취합니다. 100 번째 단계에서는 때문에 출력이 없습니다.여기서조항, 따라서 스포츠 토토 사이트가 종료됩니다.

재귀 스포츠 토토 사이트는 일반적으로 계층 적 또는 트리 구조화 된 데이터를 다루는 데 사용됩니다. 유용한 예는 즉각적인 포함을 보여주는 테이블 만 주어진 제품의 모든 직접적이고 간접적 인 하위 부분을 찾는이 쿼리입니다.

재귀 포함 포함 _parts (sub_part, part, rotity) as (
    sub_part, part, part에서 part = 'our_product'를 선택하십시오.
  모두
    p.sub_part, p.part, p.quantity * pr.quantity를 선택하십시오
    포함 _parts pr, parts p
    여기서 p.part = pr.sub_part
))
sub_part, sum (수량)을 total_quantity로 선택하십시오
conlude_parts에서
sub_part의 그룹

7.8.2.2. 사이클 감지#

재귀 쿼리로 작업 할 때 쿼리의 재귀 부분이 결국 튜플을 반환하지 않으면 쿼리가 무기한으로 반복됩니다. 때로는 사용Union대신Union All이전 출력 행을 복제하는 행을 폐기하여이를 달성 할 수 있습니다. 그러나 종종 사이클에는 완전히 복제 된 출력 행이 포함되지 않습니다. 이전에 동일한 지점에 도달했는지 확인하려면 하나 또는 몇 개의 필드 만 확인해야 할 수도 있습니다. 이러한 상황을 처리하는 표준 방법은 이미 방문한 값의 배열을 계산하는 것입니다. 예를 들어, 테이블을 검색하는 다음 쿼리를 다시 고려하십시오그래프a 사용링크필드 :

recursive search_graph (id, link, data, depth) as (
    G.ID, G.Link, G.Data, 0을 선택하십시오
    그래프 g에서
  모두
    G.ID, G.Link, G.Data, Sg.Depth + 1을 선택하십시오
    그래프 G, search_graph sg에서
    여기서 g.id = sg.link
))
sexect *에서 search_graph;

이 스포츠 토토 사이트는이면 루프됩니다.링크관계에는주기가 포함됩니다. 우리가 필요하기 때문에깊이출력, 그냥 변경Union AlltoUnion루핑을 제거하지 않습니다. 대신 우리는 특정 링크 경로를 따르면서 같은 행에 다시 도달했는지 여부를 인식해야합니다. 두 개의 열을 추가합니다is_cyclePATH루프가 발생하기 쉬운 스포츠 토토 사이트 :

with with with search_graph (id, 링크, 데이터, 깊이,is_cycle, 경로) AS (
    G.ID, G.Link, G.Data, 0, 선택거짓,
      배열 [g.id]그래프 g에서
  모두
    G.ID, G.Link, G.Data, SG.Depth + 1, 선택g.id = 모든 (경로),
      경로 || g.idGraph G, Search_Graph SG에서
    여기서 g.id = sg.linkis_cycle이 아님)
sexect *에서 search_graph;

사이클을 방지하는 것 외에도 배열 값은 종종 자체적으로 유용합니다.PATH특정 행에 도달하기 위해 촬영.

주기를 인식하기 위해 둘 이상의 필드를 점검 해야하는 일반적인 경우 행 배열을 사용하십시오. 예를 들어, 필드를 비교 해야하는 경우F1andF2:

recursive search_graph (id, 링크, 데이터, 깊이,is_cycle, 경로) AS (
    G.ID, G.Link, G.Data, 0, 선택거짓,
      배열 [행 (G.F1, G.F2)]그래프 g
  모두
    G.ID, G.Link, G.Data, SG.Depth + 1, 선택행 (G.F1, G.F2) = 모든 (경로),
      경로 || 행 (G.F1, G.F2)Graph G, Search_Graph SG에서
    여기서 g.id = sg.linkis_cycle이 아님)
sexect *에서 search_graph;

생략row ()사이클을 인식하기 위해 하나의 필드 만 확인 해야하는 공동 케이스의 구문. 이를 통해 복합 유형 배열이 아닌 간단한 배열을 사용할 수있어 효율성이 높아집니다.

사이클 감지를 단순화하기위한 구문이 내장되어 있습니다. 위의 스포츠 토토 사이트는 다음과 같이 쓸 수도 있습니다.

recursive search_graph (id, link, data, depth) as (
    G.ID, G.Link, G.Data, 1을 선택하십시오
    그래프 g에서
  모두
    G.ID, G.Link, G.Data, Sg.Depth + 1을 선택하십시오
    그래프 G, search_graph sg에서
    여기서 g.id = sg.link
)사이클 ID 세트 IS_CYCE를 사용하여 경로선택 *에서 search_graph;

그리고 내부적으로 위의 양식으로 다시 작성됩니다. 그만큼사이클절은 먼저 사이클 감지를 위해 추적 할 열 목록을 지정 한 다음 사이클이 감지되었는지 여부를 표시하는 열 이름과 마지막으로 경로를 추적 할 다른 열의 이름을 지정합니다. 사이클 및 경로 열은 CTE의 출력 행에 암시 적으로 추가됩니다.

사이클 경로 열은 이전 섹션의 깊이 우선 순서 열 표시와 같은 방식으로 계산됩니다. 쿼리에는 둘 다 가질 수 있습니다.검색및 A사이클조항, 그러나 깊이 우선 검색 사양과 사이클 감지 사양은 중복 계산을 생성하므로 만 사용하는 것이 더 효율적입니다.사이클경로 열별 절과 순서. 너비 우선 순서가 원한다면 두 가지를 지정하는 경우검색and사이클유용 할 수 있습니다.

스포츠 토토 사이트 테스트에 유용한 트릭은 루프가 a에 있는지 확실하지 않은 경우Limit부모 스포츠 토토 사이트에서. 예를 들어,이 스포츠 토토 사이트는없이 영원히 루프합니다.Limit:

재귀 t (n) as (
    선택 1
  모두
    t에서 n+1을 선택하십시오
))
t에서 n을 선택하십시오제한 100;

이것은 작동하기 때문에PostgreSQL의 구현은 많은 행의 행만 평가합니다with스포츠 토토 사이트는 실제로 상위 쿼리에 의해 가져옵니다. 다른 시스템이 다르게 작동 할 수 있으므로이 트릭을 생산에 사용하는 것은 권장되지 않습니다. 또한 외부 쿼리가 재귀 쿼리의 결과를 정렬하거나 다른 테이블에 결합하면 일반적으로 작동하지 않습니다.이 경우 외부 스포츠 토토 사이트는 일반적으로 모든를 가져 오려고합니다.with어쨌든 스포츠 토토 사이트의 출력.

7.8.3. 공통 테이블 표현 구체화#

유용한 속성with스포츠 토토 사이트는 부모 쿼리 또는 형제 자매에 의해 두 번 이상 참조 되더라도 부모 쿼리의 실행 당 한 번만 한 번만 평가된다는 것입니다with스포츠 토토 사이트. 따라서 여러 장소에서 필요한 비싼 계산은 A 내에 배치 할 수 있습니다.with중복 작업을 피하기위한 스포츠 토토 사이트. 또 다른 가능한 응용 프로그램은 부작용과 함께 함수의 원치 않는 다중 평가를 방지하는 것입니다. 그러나이 코인의 다른 쪽은 Optimizer가 상위 스포츠 토토 사이트에서 곱하기 참조로 제한을 푸시 할 수 없다는 것입니다.with스포츠 토토 사이트, 그것은 모든 용도에 영향을 줄 수 있으므로withQuery의 출력이 하나만 영향을 미치는 경우. 곱하기 참조with스포츠 토토 사이트는 상위 스포츠 토토 사이트가 나중에 버릴 수있는 행을 억제하지 않고 서면으로 평가됩니다. (그러나 위에서 언급했듯이 스포츠 토토 사이트에 대한 참조가 제한된 수의 행만 요구하면 평가가 일찍 중지 될 수 있습니다.)

그러나 awith스포츠 토토 사이트는 회수 적이지 않고 부작용이 없습니다 (즉,select휘발성 함수가 포함되지 않음) 그런 다음 부모 쿼리로 접어 두 쿼리 레벨의 공동 최적화가 가능합니다. 기본적으로 부모가 참조하는 경우 이는 발생합니다.with한 번만 스포츠 토토 사이트하지만을 참조하는 경우는 아닙니다.with두 번 이상 스포츠 토토 사이트. 지정하여 해당 결정을 무시할 수 있습니다구체화별도의 계산을 강요하려면with쿼리 또는 지정구체화되지 않음강제이를 상위 쿼리로 병합하도록합니다. 후자의 선택은의 중복 계산 위험이 있습니다.with스포츠 토토 사이트, 그러나의 각 사용이라면 여전히 순 절감 효과를 줄 수 있습니다with스포츠 토토 사이트는의 작은 부분 만 필요합니다.with스포츠 토토 사이트의 전체 출력.

이 규칙의 간단한 예는입니다.

with with (
    big_table에서 *를 선택하십시오
))
where key = 123;에서 *를 선택하십시오.

thiswith스포츠 토토 사이트가 접어서 동일한 실행 계획을 생성하여

선택 *에서 big_table where key = 123;

특히 인덱스가있는 경우, 아마도 행을 가져 오는 데 사용될 것입니다키 = 123. 반면에

with with (
    big_table에서 *를 선택하십시오
))
W1에서 W2로 W1 가입 w1에서 w1로 * w에서 *를 선택하십시오. key = w2.ref
여기서 w2. 키 = 123;

thewith쿼리가 구체화되어 임시 사본을 생성big_table지수의 혜택없이 자체와 결합됩니다. 이 스포츠 토토 사이트는로 작성되면 훨씬 더 효율적으로 실행됩니다.

구체화되지 않은 상태로 (
    big_table에서 *를 선택하십시오
))
W1에서 W2로 W1 가입 w1에서 w1로 * w에서 *를 선택하십시오. key = w2.ref
여기서 w2. 키 = 123;

부모 스포츠 토토 사이트 제한을 스캔에 직접 적용 할 수 있도록big_table.

예제구체화되지 않음바람직하지 않을 수 있습니다

w와 함께 (
    키를 선택하십시오
))
w1 as as as w2 on w1.f = w2.f;에서 w1로 w1로 *를 선택하십시오.

여기,의 구체화with스포츠 토토 사이트는very_expensive_function두 번이 아닌 테이블 행 당 한 번만 평가됩니다.

위의 예제 만 표시withselect, 그러나 같은 방식으로 첨부 할 수 있습니다삽입, 업데이트, 삭제또는병합. 각각의 경우에는 메인 명령에서 참조 할 수있는 임시 테이블을 효과적으로 제공합니다.

7.8.4. 의 데이터 수정 진술with #

데이터 수정 문 (를 사용할 수 있습니다.삽입, 업데이트, 삭제또는병합) inwith. 이를 통해 동일한 쿼리에서 여러 다른 작업을 수행 할 수 있습니다. 예는 다음과 같습니다.

maze_rows as (
    제품에서 삭제하십시오
    어디
        "날짜" = '2010-10-01'및
        "날짜"< '2010-11-01'
    반환 *
))
Products_Log에 삽입하십시오
maze_rows에서 *를 선택하십시오;

이 스포츠 토토 사이트는 효과적으로 행을 이동합니다제품toProducts_Log. 그만큼삭제inwith지정된 행을 삭제합니다제품반환절; 그리고 기본 스포츠 토토 사이트는 출력을 읽고을 삽입합니다.Products_Log.

위의 예의 미세점은입니다.with절에 첨부되어삽입, 서브select내에서삽입. 데이터 수정 진술은에만 허용되기 때문에 필요합니다.with최상위 성명서에 첨부 된 조항. 그러나 정상with가시성 규칙이 적용되므로를 참조 할 수 있습니다.withsub의 명령문 출력select.

데이터 수정 문의with보통반환조항 (참조PostgreSQL : 문서 : 17 : 6.4. 수정 된 행에서 토토 사이트 순위 반환), 위의 예와 같이. 그것은의 출력입니다.반환절,아님데이터 수정 문의 대상 테이블은 나머지 쿼리에서 참조 할 수있는 임시 테이블을 형성합니다. 데이터 수정 명세서에서with부족반환절은 임시 표를 형성하지 않으며 나머지 쿼리에서는 참조 할 수 없습니다. 그럼에도 불구하고 그러한 진술은 실행됩니다. 적절하지 않은 예는 다음과 같습니다.

t as (
    foo에서 삭제하십시오
))
바에서 삭제;

이 예제는 테이블에서 모든 행을 제거합니다foobar. 클라이언트에보고 된 영향을받는 행의 수에는에서만 제거 된 행만 포함됩니다.bar.

데이터 수정 문의 재귀 적 자기 참조는 허용되지 않습니다. 경우에 따라 재귀의 출력을 참조 하여이 제한을 해결할 수 있습니다with, 예 :

재귀 포함 포함 _parts (sub_part, part) as (
    sub_part, part = 'our_product'부분에서 부품을 선택하십시오.
  모두
    p.sub_part, p.part를 선택하십시오
    포함 _parts pr, parts p
    여기서 p.part = pr.sub_part
))
부품에서 삭제하십시오
  PART (conture_Parts에서 부품을 선택);

이 스포츠 토토 사이트는 제품의 모든 직접적이고 간접적 인 하위 부분을 제거합니다.

데이터 수정 문의with는 1 차 쿼리가 출력의 모든 (또는 실제로)를 읽는지 여부와 독립적으로 한 번 정확하게 한 번 실행되며 항상 완료됩니다. 이것은 규칙과 다릅니다selectinwith: 이전 섹션에서 언급 한 바와 같이, aselect기본 스포츠 토토 사이트가 출력을 요구하는 한만 운반됩니다.

하위 진술의with는 서로 동시에 그리고 기본 스포츠 토토 사이트와 함께 실행됩니다. 따라서 데이터 수정 문을 사용할 때with, 지정된 업데이트가 실제로 발생하는 순서는 예측할 수 없습니다. 모든 진술은 동일하게 실행됩니다스냅 샷(참조PostgreSQL : 문서 : 17 : 13 장. 스포츠 토토 사이트 제어), 따라서참조대상 테이블에 대한 서로의 영향. 이것은 실제 행 업데이트의 실제 순서의 예측 불가능 성의 영향을 완화하며반환데이터는 다른간에 변경 사항을 전달하는 유일한 방법입니다with하위 진술 및 기본 스포츠 토토 사이트. 이것의 예는에서입니다.

t as (
    업데이트 제품 세트 가격 = 가격 * 1.05
    반환 *
))
선택 *에서 제품에서;

외부select의 행동 전에 원래 가격을 반환합니다업데이트

t as (
    업데이트 제품 세트 가격 = 가격 * 1.05
    반환 *
))
선택 *에서 t; 선택

외부select업데이트 된 데이터를 반환합니다.

단일 문서에서 같은 행을 두 번 업데이트하려는 것은 지원되지 않습니다. 수정 중 하나만 발생하지만 어느 것을 쉽게 예측하는 것은 쉽지 않으며 때로는 불가능합니다. 이는 동일한 문서에서 이미 업데이트 된 행을 삭제하는데도 적용됩니다. 업데이트 만 수행됩니다. 따라서 일반적으로 단일 문서에서 단일 행을 두 번 수정하지 않아야합니다. 특히 글쓰기를 피하십시오with메인 문 또는 형제 자매 하위 진술에 의해 변경된 동일한 행에 영향을 줄 수있는 하위 진술. 그러한 진술의 효과는 예측할 수 없습니다.

현재, 데이터 수정 명령문의 대상으로 사용되는 모든 테이블with조건부 규칙도 없어야합니다.또한규칙, 또는대신여러 진술로 확장하는 규칙.

정정 제출

문서에 맞지 않는 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 귀하의 경험 또는 추가 설명이 필요합니다. 사용이 양식문서 문제를보고하려면