7.8. 함께토토 사이트 추천(공통 테이블 표현식)

WITH더 큰 쿼리에 사용할 보조 문을 작성하는 방법을 제공합니다. 공통 테이블 표현식이라고도 하는 이러한 명령문은 다음과 같습니다.CTEs는 하나의 토토 사이트 추천에만 존재하는 임시 테이블을 정의하는 것으로 생각할 수 있습니다. a의 각 보조 문WITH절은 다음과 같습니다.선택, 삽입, 업데이트, 또는삭제; 그리고위드절 자체는 다음이 될 수도 있는 기본 명령문에 첨부됩니다.선택, 삽입, 업데이트또는삭제.

7.8.1. 선택WITH

기본값선택함께복잡한 쿼리를 더 간단한 부분으로 나누는 것입니다. 예는 다음과 같습니다:

regional_sales AS 사용(
    SELECT 지역, SUM(금액) AS total_sales
    주문에서
    지역별로 그룹화
), top_regions AS(
    지역 선택
    Regional_sales에서
    WHERE total_sales  (SELECT SUM(total_sales)/10 FROM Regional_sales)
)
지역 선택,
       제품,
       SUM(수량) AS 제품_단위,
       SUM(금액) AS 제품_판매
주문에서
WHERE 지역 IN(top_regions에서 지역 선택)
지역, 제품별로 그룹화;

최고 판매 지역에서만 제품별 판매 총계를 표시합니다. 그만큼WITH절은 이름이 지정된 두 개의 보조 문을 정의합니다.regional_sales그리고top_regions, 여기서 출력은regional_sales다음에서 사용됨top_regions및 출력top_regions기본에서 사용됩니다선택질의. 이 예는 없이 작성되었을 수 있습니다.WITH, 하지만 두 가지 수준의 중첩 하위가 필요했습니다.선택s. 이 방법을 따르면 조금 더 쉽습니다.

7.8.2. 재귀 쿼리

선택사항반복수정자 변경WITH단순한 구문적 편리성에서 표준 SQL에서는 불가능했던 기능을 수행하는 기능으로 바뀌었습니다. 사용반복, 아함께토토 사이트 추천는 자체 출력을 참조할 수 있습니다. 매우 간단한 예는 1부터 100까지의 정수를 합산하는 토토 사이트 추천입니다.

재귀적 t(n) AS 사용(
    가치 (1)
  유니온 올
    n < 100인 t WHERE에서 n+1 선택
)
SELECT 합계(n) FROM t;

재귀의 일반적인 형태위드토토 사이트 추천는 항상 a비재귀 용어그러면유니온(또는유니온 올), 그런 다음 a재귀 용어, 여기서 재귀 용어만 쿼리 자체 출력에 대한 참조를 포함할 수 있습니다. 이러한 쿼리는 다음과 같이 실행됩니다.

재귀 토토 사이트 추천 평가

  1. 비재귀적 용어를 평가합니다. 에 대한유니온(그러나 아님유니온 올), 중복 행을 삭제합니다. 재귀 쿼리 결과에 나머지 행을 모두 포함하고 임시 저장소에 배치합니다.작업 테이블.

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

    1. 재귀적 자기 참조를 작업 테이블의 현재 내용으로 대체하여 재귀적 용어를 평가합니다. 에 대한유니온(그러나 아님유니온 올), 중복 행 및 이전 결과 행과 중복되는 행을 삭제합니다. 재귀 쿼리 결과에 나머지 행을 모두 포함하고 임시 저장소에 배치합니다.중간 테이블.

    2. 작업 테이블의 내용을 중간 테이블의 내용으로 바꾼 다음 중간 테이블을 비우십시오.

참고

그동안반복쿼리를 재귀적으로 지정할 수 있으며 내부적으로 이러한 쿼리는 반복적으로 평가됩니다.

위의 예에서 작업 테이블은 각 단계마다 단 하나의 행만 가지며 연속적인 단계에서 1부터 100까지의 값을 취합니다. 100번째 단계에서는 다음과 같은 이유로 출력이 없습니다.어디에서절이므로 토토 사이트 추천가 종료됩니다.

재귀 쿼리는 일반적으로 계층적 또는 트리 구조 데이터를 처리하는 데 사용됩니다. 유용한 예는 즉각적인 포함을 표시하는 테이블만 주어진 경우 제품의 모든 직접 및 간접 하위 부분을 찾는 이 쿼리입니다.

재귀적 include_parts(하위 부품, 부품, 수량) AS(
    SELECT sub_part, 부품, 수량 FROM 부품 WHERE 부품 = '우리_제품'
  유니온 올
    SELECT p.sub_part, p.part, p.수량 * pr.수량
    FROM include_parts pr, 부품 p
    여기서 p.part = pr.sub_part
)
SELECT sub_part, SUM(수량)을 total_수량으로 선택
포함된 부품에서
GROUP BY 하위_부분

7.8.2.2. 사이클 감지

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

재귀 검색_그래프(id, 링크, 데이터, 깊이) AS(
    SELECT g.id, g.link, g.data, 0
    FROM 그래프 g
  유니온 올
    SELECT g.id, g.link, g.data, sg.length + 1
    FROM 그래프 g, search_graph sg
    어디에서 g.id = sg.link
)
SELECT * 검색_그래프에서;

이 쿼리는 다음과 같은 경우 반복됩니다.링크관계에는 주기가 포함되어 있습니다. 왜냐하면 우리는 a를 요구하기 때문입니다.깊이출력, 변경 중유니온 올유니온루핑을 제거하지 못할 것입니다. 대신에 우리는 특정 링크 경로를 따라가면서 다시 같은 행에 도달했는지 여부를 인식해야 합니다. 두 개의 열을 추가합니다is_cycle그리고경로루프가 발생하기 쉬운 토토 사이트 추천에 대해:

반복 검색_그래프(id, 링크, 데이터, 깊이,is_cycle, 경로) 그대로(
    SELECT g.id, g.link, g.data, 0,거짓,
      ARRAY[g.id]그래프 g에서
  유니온 올
    SELECT g.id, g.link, g.data, sg.length + 1,g.id = 모두(경로),
      경로 || g.idFROM 그래프 g, search_graph sg
    어디에서 g.id = sg.linkis_cycle 아님)
SELECT * 검색_그래프에서;

주기를 방지하는 것 외에도 배열 값은 종종 그 자체로 다음을 나타내는 데 유용합니다.경로특정 행에 도달하기 위해 사용됩니다.

주기를 인식하기 위해 하나 이상의 필드를 확인해야 하는 일반적인 경우 행 배열을 사용하십시오. 예를 들어 필드를 비교해야 하는 경우f1그리고f2:

반복 검색_그래프(id, 링크, 데이터, 깊이,is_cycle, 경로) 그대로(
    SELECT g.id, g.link, g.data, 0,거짓,
      ARRAY[ROW(g.f1, g.f2)]그래프 g에서
  유니온 올
    SELECT g.id, g.link, g.data, sg.length + 1,ROW(g.f1, g.f2) = 모두(경로),
      경로 || 행(g.f1, g.f2)FROM 그래프 g, search_graph sg
    어디에서 g.id = sg.linkis_cycle이 아님)
SELECT * 검색_그래프에서;

생략ROW()주기를 인식하기 위해 하나의 필드만 확인하면 되는 일반적인 경우의 구문입니다. 이를 통해 복합형 배열이 아닌 간단한 배열을 사용할 수 있어 효율성이 향상됩니다.

주기 감지를 단순화하는 구문이 내장되어 있습니다. 위 쿼리는 다음과 같이 작성할 수도 있습니다.

재귀 검색_그래프(id, 링크, 데이터, 깊이) AS(
    SELECT g.id, g.link, g.data, 1
    FROM 그래프 g
  유니온 올
    SELECT g.id, g.link, g.data, sg.length + 1
    FROM 그래프 g, search_graph sg
    어디에서 g.id = sg.link
)사이클 ID 설정 is_cycle USING 경로SELECT * FROM search_graph;

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

주기 경로 열은 이전 섹션에 표시된 깊이 우선 정렬 열과 동일한 방식으로 계산됩니다. 쿼리에는 다음과 같은 두 가지가 모두 포함될 수 있습니다.검색그리고사이클절이지만 깊이 우선 검색 사양과 주기 감지 사양은 중복 계산을 생성하므로 그냥 사용하는 것이 더 효율적입니다.사이클경로 열을 기준으로 절 및 순서를 지정합니다. 너비 우선 정렬을 원하는 경우 둘 다 지정하십시오.검색그리고사이클유용할 수 있어요.

쿼리의 반복 여부가 확실하지 않을 때 쿼리를 테스트하는 데 유용한 방법은 다음을 배치하는 것입니다.제한상위 쿼리에서. 예를 들어 이 쿼리는가 없으면 영원히 반복됩니다.제한:

재귀적 t(n) AS 사용(
    1개를 선택하세요
  유니온 올
    t에서 n+1 선택
)
t에서 n을 선택하세요.한도 100;

이것은 작동하는 이유는 다음과 같습니다.PostgreSQL의 구현은 a의 행만큼만 평가합니다.함께쿼리는 실제로 상위 쿼리에 의해 가져옵니다. 다른 시스템이 다르게 작동할 수 있으므로 프로덕션에서는 이 트릭을 사용하지 않는 것이 좋습니다. 또한 외부 쿼리가 재귀 쿼리의 결과를 정렬하거나 다른 테이블에 조인하도록 하면 일반적으로 작동하지 않습니다. 왜냐하면 이러한 경우 외부 쿼리는 일반적으로 모든 결과를 가져오려고 시도하기 때문입니다.함께어쨌든 토토 사이트 추천의 출력입니다.

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

유용한 속성함께쿼리는 상위 쿼리 또는 형제에 의해 두 번 이상 참조되더라도 일반적으로 상위 쿼리 실행당 한 번만 평가된다는 점입니다.위드토토 사이트 추천. 따라서 여러 장소에서 필요한 값비싼 계산을 a 내에 배치할 수 있습니다.위드중복된 작업을 피하기 위한 쿼리입니다. 또 다른 가능한 적용은 부작용이 있는 기능에 대한 원치 않는 다중 평가를 방지하는 것입니다. 그러나 이 동전의 다른 측면은 최적화 프로그램이 상위 쿼리의 제한 사항을 다중 참조 쿼리로 푸시할 수 없다는 것입니다.위드쿼리, 이는 모든 사용에 영향을 미칠 수 있으므로위드토토 사이트 추천의 출력이 하나만 영향을 받아야 하는 경우. 다중 참조WITH쿼리는 나중에 상위 쿼리가 삭제할 수 있는 행을 억제하지 않고 작성된 대로 평가됩니다. (그러나 위에서 언급한 것처럼 쿼리에 대한 참조가 제한된 수의 행만 요구하는 경우 평가가 조기에 중지될 수 있습니다.)

그러나 만일 a위드토토 사이트 추천는 비재귀적이고 부작용이 없습니다(즉,선택휘발성 함수 없음) 상위 토토 사이트 추천로 접혀 두 토토 사이트 추천 수준의 공동 최적화가 가능합니다. 기본적으로 이는 상위 토토 사이트 추천가를 참조하는 경우 발생합니다.WITH한 번만 토토 사이트 추천하세요. 그러나 참조하는 경우에는 토토 사이트 추천하지 마세요.WITH두 번 이상 쿼리하세요. 다음을 지정하여 해당 결정을 무시할 수 있습니다.구체화됨별도의 계산을 강제하기 위해WITH질의하거나 지정하여구현되지 않음강제적으로 상위 쿼리에 병합됩니다. 후자를 선택하면의 중복 계산 위험이 있습니다.함께쿼리를 수행하지만 각 사용 시 순 절감 효과를 얻을 수 있습니다.WITH토토 사이트 추천에는 극히 일부만 필요합니다.WITH토토 사이트 추천의 전체 출력입니다.

이러한 규칙의 간단한 예는 다음과 같습니다.

WITH AS(
    SELECT * FROM big_table
)
SELECT * FROM w WHERE 키 = 123;

이것함께쿼리가 접혀서 다음과 동일한 실행 계획이 생성됩니다.

SELECT * FROM big_table WHERE 키 = 123;

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

WITH AS(
    SELECT * FROM big_table
)
SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref
w2.key = 123;

함께토토 사이트 추천가 구체화되어 임시 복사본이 생성됩니다.big_table그런 다음 색인의 이점 없이 자체적으로 결합됩니다. 이 쿼리는 다음과 같이 작성하면 훨씬 더 효율적으로 실행됩니다.

구현되지 않은 상태(
    SELECT * FROM big_table
)
SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref
w2.key = 123;

상위 쿼리의 제한 사항을 스캔에 직접 적용할 수 있도록big_table.

예시구현되지 않음바람직하지 않을 수도 있습니다

WITH AS(
    SELECT 키, very_expensive_function(val) as f FROM some_table
)
SELECT * FROM w AS w1 JOIN w AS w2 ON w1.f = w2.f;

여기서, 물질화는함께토토 사이트 추천가 보장합니다매우_비싼_기능테이블 행당 한 번만 평가되며 두 번은 평가되지 않습니다.

위의 예는 단지 보여줍니다.WITH다음과 함께 사용 중선택, 하지만 동일한 방식으로 연결할 수 있습니다.삽입, 업데이트또는삭제. 각 경우에 기본 명령에서 참조할 수 있는 임시 테이블을 효과적으로 제공합니다.

7.8.4. 의 데이터 수정 문WITH

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

moved_rows AS 사용(
    제품에서 삭제
    어디서
        "날짜" = '2010-10-01' AND
        "날짜" < '2010-11-01'
    돌아오는 중 *
)
products_log에 삽입
SELECT * 이동된 행에서;

이 쿼리는 효과적으로 행을 다음에서 이동합니다.제품제품_로그.삭제함께다음에서 지정된 행을 삭제합니다.제품, 해당을 통해 내용을 반환합니다.돌아오는 중절; 그런 다음 기본 쿼리는 해당 출력을 읽고 이를 다음에 삽입합니다.제품_로그.

위 예의 좋은 점은 다음과 같습니다.함께절이 다음에 첨부됩니다.삽입, 하위가 아님-선택내부삽입. 데이터 수정 문은 다음에서만 허용되기 때문에 필요합니다.함께최상위 명령문에 첨부된 절. 그러나 정상WITH가시성 규칙이 적용되므로 다음을 참조할 수 있습니다.함께하위문의 출력선택.

데이터 수정 명령문함께보통은돌아오는 중절(참조PostgreSQL : 문서 : 14 : 6.4. 수정 된 행에서 배트맨 토토 반환), 위의 예에 표시된 대로입니다. 의 출력입니다.돌아오는 중절,아님토토 사이트 추천의 나머지 부분에서 참조할 수 있는 임시 테이블을 형성하는 데이터 수정 문의 대상 테이블입니다. 데이터 수정 문이 있는 경우함께a가 부족함돌아오는 중절인 경우 임시 테이블을 형성하지 않으며 쿼리의 나머지 부분에서 참조할 수 없습니다. 그럼에도 불구하고 그러한 명령문은 실행됩니다. 특별히 유용하지 않은 예는 다음과 같습니다.

AS로(
    foo에서 삭제
)
막대에서 삭제;

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

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

반복적 include_parts(하위_부분, 부분) AS(
    SELECT sub_part, 부품 FROM 부품 WHERE 부품 = 'our_product'
  유니온 올
    SELECT p.sub_part, p.part
    FROM include_parts pr, 부품 p
    여기서 p.part = pr.sub_part
)
부품에서 삭제
  WHERE 부분 IN(included_parts에서 부분 선택);

이 쿼리는 제품의 직접 및 간접 하위 부분을 모두 제거합니다.

데이터 수정 명령문위드은 기본 쿼리가 출력의 전부(또는 실제로 일부)를 읽는지 여부와 관계없이 정확히 한 번 실행되고 항상 완료됩니다. 이는 다음의 규칙과 다릅니다.선택inWITH: 이전 섹션에서 설명한 대로 a 실행선택기본 토토 사이트 추천가 출력을 요구하는 경우에만 전달됩니다.

다음의 하위 진술함께은 서로 동시에 그리고 기본 쿼리와 함께 실행됩니다. 따라서 다음에서 데이터 수정 문을 사용할 때WITH, 지정된 업데이트가 실제로 발생하는 순서는 예측할 수 없습니다. 모든 명령문은 동일하게 실행됩니다.스냅샷(참조PostgreSQL : 문서 : 14 : 13 장. 스포츠 토토 결과 제어), 그래서 그들은 할 수 없습니다참조서로 목표 테이블에 미치는 영향. 이는 행 업데이트의 실제 순서를 예측할 수 없는 영향을 완화하며 다음을 의미합니다.돌아오는 중데이터는 서로 다른 변경 사항을 전달하는 유일한 방법입니다.함께하위 명령문 및 기본 쿼리. 이에 대한 예는 다음과 같습니다.

WITH AS(
    UPDATE 제품 SET 가격 = 가격 * 1.05
    돌아오는 중 *
)
SELECT * FROM 제품;

바깥쪽선택조치 이전의 원래 가격을 반환합니다업데이트, 안에 있는 동안

AS로 (
    UPDATE 제품 SET 가격 = 가격 * 1.05
    돌아오는 중 *
)
t에서 * 선택;

바깥쪽선택업데이트된 데이터를 반환합니다.

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

현재 다음에서 데이터 수정 문의 대상으로 사용되는 모든 테이블함께조건부 규칙이나이 없어야 합니다.또한규칙도 아니고대신여러 문으로 확장되는 규칙.

수정 사항 제출

문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 경험이 있거나 추가 설명이 필요한 경우 이용해주세요이 양식문서 문제를 보고합니다.