함께메이저 토토 사이트(공통 테이블 표현식)#WITH더 큰 쿼리에 사용할 보조 문을 작성하는 방법을 제공합니다. 공통 테이블 표현식이라고도 하는 이러한 명령문은 다음과 같습니다.CTEs는 하나의 메이저 토토 사이트에만 존재하는 임시 테이블을 정의하는 것으로 생각할 수 있습니다. a의 각 보조 문위드절은 다음과 같습니다.선택, 삽입, 업데이트, 삭제또는병합; 그리고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기본에서 사용됩니다선택질의. 이 예는 없이 작성되었을 수 있습니다.함께, 하지만 두 가지 수준의 중첩 하위가 필요했습니다.선택s. 이 방법을 따르면 조금 더 쉽습니다.
선택사항반복수정자 변경위드단순한 구문적 편리성에서 표준 SQL에서는 불가능했던 기능을 수행하는 기능으로 바뀌었습니다. 사용반복, 아WITH메이저 토토 사이트는 자체 출력을 참조할 수 있습니다. 매우 간단한 예는 1부터 100까지의 정수를 합산하는 메이저 토토 사이트입니다.
재귀적 t(n) AS 사용(
가치 (1)
유니온 올
n < 100인 t WHERE에서 n+1 선택
)
SELECT 합계(n) FROM t;
재귀의 일반적인 형태위드메이저 토토 사이트는 항상 a비재귀 용어그러면유니온(또는유니온 올), 그런 다음 a재귀 용어, 여기서 재귀 용어만 쿼리 자체 출력에 대한 참조를 포함할 수 있습니다. 이러한 쿼리는 다음과 같이 실행됩니다.
재귀적 메이저 토토 사이트 평가
비재귀적 용어를 평가합니다. 에 대한유니온(그러나 아님유니온 올), 중복 행을 삭제합니다. 재귀 쿼리 결과에 나머지 행을 모두 포함하고 임시 저장소에 배치합니다.작업 테이블.
작업 테이블이 비어 있지 않은 한 다음 단계를 반복하십시오:
재귀적 자기 참조를 작업 테이블의 현재 내용으로 대체하여 재귀적 용어를 평가합니다. 에 대한유니온(그러나 아님유니온 올), 중복 행 및 이전 결과 행과 중복되는 행을 삭제합니다. 재귀 쿼리 결과에 나머지 행을 모두 포함하고 임시 저장소에 배치합니다.중간 테이블.
작업 테이블의 내용을 중간 테이블의 내용으로 대체한 다음 중간 테이블을 비우십시오.
그동안반복쿼리를 재귀적으로 지정할 수 있으며 내부적으로 이러한 쿼리는 반복적으로 평가됩니다.
위의 예에서 작업 테이블은 각 단계마다 단 하나의 행만 가지며 연속적인 단계에서 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 하위_부분
재귀 쿼리를 사용하여 트리 순회를 계산할 때 깊이 우선 또는 너비 우선 순서로 결과를 정렬할 수 있습니다. 이는 다른 데이터 열과 함께 정렬 열을 계산하고 이를 사용하여 마지막에 결과를 정렬함으로써 수행될 수 있습니다. 이는 쿼리 평가가 행을 방문하는 순서를 실제로 제어하지 않는다는 점에 유의하세요. 이는 항상 SQL 구현에 따라 다릅니다. 이 접근 방식은 나중에 결과를 정렬하는 편리한 방법을 제공할 뿐입니다.
깊이 우선 순서를 생성하기 위해 각 결과 행에 대해 지금까지 방문한 행 배열을 계산합니다. 예를 들어 테이블을 검색하는 다음 쿼리를 생각해 보세요.나무사용링크필드:
재귀 검색_트리(ID, 링크, 데이터) AS(
t.id, t.link, t.data 선택
트리 t에서
유니온 올
t.id, t.link, t.data 선택
FROM 트리 t, search_tree st
여기서 t.id = st.link
)
SELECT * 검색_트리에서;
깊이 우선 순서 정보를 추가하려면 다음과 같이 작성할 수 있습니다.
반복 검색_트리(ID, 링크, 데이터,경로) 그대로( t.id, t.link, t.data를 선택하세요.ARRAY[t.id]나무에서 t 유니온 올 t.id, t.link, t.data를 선택하세요.경로 || t.idFROM 트리 t, search_tree st 여기서 t.id = st.link ) 선택 * 검색_트리에서경로별 주문;
행을 식별하기 위해 둘 이상의 필드를 사용해야 하는 일반적인 경우 행 배열을 사용하십시오. 예를 들어 필드를 추적해야 하는 경우f1그리고f2:
재귀적 검색_트리(ID, 링크, 데이터,경로) 그대로( t.id, t.link, t.data를 선택하세요.ARRAY[ROW(t.f1, t.f2)]나무에서 t 유니온 올 t.id, t.link, t.data를 선택하세요.경로 || 행(t.f1, t.f2)FROM 트리 t, search_tree st 여기서 t.id = st.link ) 선택 * 검색_트리에서경로별 주문;
생략ROW()단 하나의 필드만 추적해야 하는 일반적인 경우의 구문입니다. 이를 통해 복합형 배열이 아닌 간단한 배열을 사용할 수 있어 효율성이 향상됩니다.
너비 우선 순서를 생성하려면 검색 깊이를 추적하는 열을 추가할 수 있습니다. 예를 들면 다음과 같습니다.
반복 검색_트리(id, 링크, 데이터,깊이) 그대로( t.id, t.link, t.data를 선택하세요.0나무에서 t 유니온 올 t.id, t.link, t.data를 선택하세요.깊이 + 1FROM 트리 t, search_tree st 여기서 t.id = st.link ) 선택 * 검색_트리에서깊이별 주문;
안정적인 정렬을 얻으려면 데이터 열을 보조 정렬 열로 추가하세요.
재귀 메이저 토토 사이트 평가 알고리즘은 너비 우선 검색 순서로 출력을 생성합니다. 그러나 이는 구현 세부 사항이므로 이에 의존하는 것은 바람직하지 않을 수 있습니다. 각 수준 내의 행 순서는 확실히 정의되지 않았으므로 어떤 경우에도 명시적인 순서가 필요할 수 있습니다.
깊이 우선 또는 너비 우선 정렬 열을 계산하는 구문이 내장되어 있습니다. 예를 들면:
재귀 검색_트리(ID, 링크, 데이터) AS(
t.id, t.link, t.data 선택
트리 t에서
유니온 올
t.id, t.link, t.data 선택
FROM 트리 t, search_tree st
여기서 t.id = st.link
)ID SET ordercol로 깊이 우선 검색SELECT * FROM search_tree ORDER BY ordercol;
WITH RECURSIVE 검색_트리(ID, 링크, 데이터) AS(
t.id, t.link, t.data 선택
트리 t에서
유니온 올
t.id, t.link, t.data 선택
FROM 트리 t, search_tree st
여기서 t.id = st.link
)ID SET ordercol로 너비 우선 검색SELECT * FROM search_tree ORDER BY ordercol;
이 구문은 위의 손으로 작성한 형식과 유사한 것으로 내부적으로 확장됩니다.검색절은 깊이 우선 검색이 필요한지 너비 우선 검색이 필요한지 여부, 정렬을 위해 추적할 열 목록, 정렬에 사용할 수 있는 결과 데이터가 포함될 열 이름을 지정합니다. 해당 열은 CTE의 출력 행에 암시적으로 추가됩니다.
재귀 쿼리로 작업할 때 쿼리의 재귀 부분이 결국 튜플을 반환하지 않는지 확인하는 것이 중요합니다. 그렇지 않으면 쿼리가 무한정 반복됩니다. 때로는 다음을 사용하여유니온대신에유니온 전체이전 출력 행을 복제하는 행을 삭제하여 이를 수행할 수 있습니다. 그러나 주기에는 완전히 중복된 출력 행이 포함되지 않는 경우가 많습니다. 이전에 동일한 지점에 도달했는지 확인하려면 하나 또는 몇 개의 필드만 확인해야 할 수도 있습니다. 이러한 상황을 처리하는 표준 방법은 이미 방문한 값의 배열을 계산하는 것입니다. 예를 들어, 테이블을 검색하는 다음 쿼리를 다시 생각해 보세요.그래프사용링크필드:
재귀 검색_그래프(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]FROM 그래프 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()25790_25975
주기 감지를 단순화하기 위한 구문이 내장되어 있습니다. 위 쿼리는 다음과 같이 작성할 수도 있습니다.
재귀 검색_그래프(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;
이것은 작동하는 이유는 다음과 같습니다.포스트그레SQL의 구현은 a의 행만큼만 평가합니다.위드쿼리는 실제로 상위 쿼리에 의해 가져옵니다. 다른 시스템이 다르게 작동할 수 있으므로 프로덕션에서는 이 트릭을 사용하지 않는 것이 좋습니다. 또한 외부 쿼리가 재귀 쿼리의 결과를 정렬하거나 다른 테이블에 조인하도록 하면 일반적으로 작동하지 않습니다. 왜냐하면 이러한 경우 외부 쿼리는 일반적으로 모든 결과를 가져오려고 시도하기 때문입니다.함께어쨌든 메이저 토토 사이트의 출력입니다.
유용한 속성위드쿼리는 상위 쿼리 또는 형제에 의해 두 번 이상 참조되더라도 일반적으로 상위 쿼리 실행당 한 번만 평가된다는 점입니다.위드메이저 토토 사이트. 따라서 여러 장소에서 필요한 값비싼 계산을 a 내에 배치할 수 있습니다.위드중복된 작업을 피하기 위한 쿼리입니다. 또 다른 가능한 적용은 부작용이 있는 기능에 대한 원치 않는 다중 평가를 방지하는 것입니다. 그러나 이 동전의 다른 측면은 최적화 프로그램이 상위 쿼리의 제한 사항을 다중 참조 쿼리로 푸시할 수 없다는 것입니다.함께쿼리, 이는 모든 사용에 영향을 미칠 수 있으므로함께메이저 토토 사이트의 출력이 하나만 영향을 받아야 할 때. 다중 참조위드쿼리는 나중에 상위 쿼리가 삭제할 수 있는 행을 억제하지 않고 작성된 대로 평가됩니다. (그러나 위에서 언급한 것처럼 쿼리에 대한 참조가 제한된 수의 행만 요구하는 경우 평가가 조기에 중지될 수 있습니다.)
그러나 만일 aWITH메이저 토토 사이트는 비재귀적이고 부작용이 없습니다(즉,선택휘발성 함수 없음) 상위 메이저 토토 사이트로 접어서 두 메이저 토토 사이트 수준을 공동으로 최적화할 수 있습니다. 기본적으로 이는 상위 메이저 토토 사이트가를 참조하는 경우 발생합니다.함께한 번만 메이저 토토 사이트하십시오. 그러나 참조하는 경우에는 그렇지 않습니다.함께두 번 이상 쿼리하세요. 다음을 지정하여 해당 결정을 무시할 수 있습니다.구체화됨별도의 계산을 강제하기 위해함께질의하거나 지정하여구현되지 않음강제적으로 상위 쿼리에 병합됩니다. 후자를 선택하면의 중복 계산 위험이 있습니다.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;
the위드메이저 토토 사이트가 구체화되어 임시 복사본이 생성됩니다.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메이저 토토 사이트가 보장합니다매우_비싼_기능테이블 행당 한 번만 평가되며 두 번은 평가되지 않습니다.
위의 예는 단지 보여줍니다.WITH다음과 함께 사용 중선택, 하지만 같은 방식으로 연결할 수 있습니다.삽입, 업데이트, 삭제, 또는병합. 각 경우에 기본 명령에서 참조할 수 있는 임시 테이블을 효과적으로 제공합니다.
함께 #데이터 수정 문을 사용할 수 있습니다(삽입, 업데이트, 삭제또는병합) in함께. 이를 통해 동일한 쿼리에서 여러 가지 다른 작업을 수행할 수 있습니다. 예는 다음과 같습니다:
moved_rows AS(
제품에서 삭제
어디서
"날짜" = '2010-10-01' AND
"날짜" < '2010-11-01'
돌아오는 중 *
)
products_log에 삽입
SELECT * 이동된 행에서;
이 쿼리는 효과적으로 행을 다음에서 이동합니다.제품에제품_로그.삭제in함께다음에서 지정된 행을 삭제합니다.제품, 해당를 통해 내용을 반환합니다.돌아오는 중절; 그런 다음 기본 쿼리는 해당 출력을 읽고 이를 다음에 삽입합니다.제품_로그.
위 예의 좋은 점은 다음과 같습니다.함께절이 다음에 첨부되어 있습니다.삽입, 하위가 아님-선택내부삽입. 데이터 수정 문은 다음에서만 허용되기 때문에 필요합니다.함께최상위 명령문에 첨부된 절. 그러나 정상함께가시성 규칙이 적용되므로 다음을 참조할 수 있습니다.함께하위문의 출력선택.
데이터 수정 명령문함께보통은돌아오는 중절(참조PostgreSQL : 문서 : 18 : 6.4. 수정 된 행에서 토토 사이트 순위 반환), 위의 예에 표시된 대로입니다. 의 출력입니다.돌아오는 중절,아님메이저 토토 사이트의 나머지 부분에서 참조할 수 있는 임시 테이블을 형성하는 데이터 수정 문의 대상 테이블입니다. 데이터 수정 문이 있는 경우함께부족돌아오는 중절인 경우 임시 테이블을 형성하지 않으며 쿼리의 나머지 부분에서 참조할 수 없습니다. 그럼에도 불구하고 그러한 명령문은 실행됩니다. 특별히 유용하지 않은 예는 다음과 같습니다.
AS로(
foo에서 삭제
)
막대에서 삭제;
이 예는 테이블에서 모든 행을 제거합니다.foo그리고바. 클라이언트에 보고된 영향을 받은 행 수에는 제거된 행만 포함됩니다.바.
데이터 수정 문의 재귀적 자체 참조는 허용되지 않습니다. 어떤 경우에는 재귀의 출력을 참조하여 이 제한을 해결할 수 있습니다.함께, 예:
재귀적 포함 포함_부분(하위 부분, 부분) 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에서 부분 선택);
이 쿼리는 제품의 직접 및 간접 하위 부분을 모두 제거합니다.
데이터 수정 명령문함께은 기본 쿼리가 출력의 전부(또는 실제로 일부)를 읽는지 여부에 관계없이 정확히 한 번 실행되고 항상 완료됩니다. 이는 다음의 규칙과 다릅니다.선택에함께: 이전 섹션에서 설명한 대로 a 실행선택기본 메이저 토토 사이트가 출력을 요구하는 경우에만 전달됩니다.
다음의 하위 진술함께은 서로 동시에 그리고 기본 쿼리와 함께 실행됩니다. 따라서 다음에서 데이터 수정 문을 사용할 때함께, 지정된 업데이트가 실제로 발생하는 순서는 예측할 수 없습니다. 모든 명령문은 동일하게 실행됩니다.스냅샷(참조토토 커뮤니티 : 문서 : 18 : 13 장. 동시성 제어), 그래서 그들은 할 수 없습니다“참조”서로가 목표 테이블에 미치는 영향. 이는 행 업데이트의 실제 순서를 예측할 수 없는 영향을 완화하며 다음을 의미합니다.돌아오는 중데이터는 서로 다른 변경 사항을 전달하는 유일한 방법입니다.함께하위 명령문 및 기본 쿼리. 이에 대한 예는 다음과 같습니다.
AS로(
UPDATE 제품 SET 가격 = 가격 * 1.05
돌아오는 중 *
)
SELECT * FROM 제품;
외부선택작업 이전의 원래 가격을 반환합니다.업데이트, 안에 있는 동안
AS를 사용하여(
UPDATE 제품 SET 가격 = 가격 * 1.05
돌아오는 중 *
)
t에서 * 선택;
바깥쪽선택업데이트된 데이터를 반환합니다.
단일 명령문에서 동일한 행을 두 번 업데이트하려는 시도는 지원되지 않습니다. 수정 중 하나만 발생하지만 어느 수정인지 예측하는 것은 쉽지 않으며 때로는 불가능합니다. 이는 동일한 명령문에서 이미 업데이트된 행을 삭제하는 경우에도 적용됩니다. 업데이트만 수행됩니다. 따라서 일반적으로 단일 명령문에서 단일 행을 두 번 수정하는 것을 피해야 합니다. 특히 글쓰기를 피하세요함께주 문 또는 형제 하위 문에 의해 변경된 동일한 행에 영향을 미칠 수 있는 하위 문. 그러한 진술의 결과는 예측할 수 없습니다.
현재 다음에서 데이터 수정 문의 대상으로 사용되는 모든 테이블함께조건부 규칙이나이 없어야 합니다.또한규칙도 아니고대신여러 문으로 확장되는 규칙.
문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 경험이 있거나 추가 설명이 필요한 경우 이용해주세요이 양식문서 문제를 보고합니다.