교차 조인은 두 세트의 튜플에서 데카르트 곱을 수행합니다.
SELECT *
FROM Table1
CROSS JOIN Table2
어떤 상황에서 그러한 SQL 작업이 특히 유용합니까?
교차 조인은 두 세트의 튜플에서 데카르트 곱을 수행합니다.
SELECT *
FROM Table1
CROSS JOIN Table2
어떤 상황에서 그러한 SQL 작업이 특히 유용합니까?
답변:
특정 의류 품목에 대한 크기 및 색상 정보와 같이 완전히 채우려는 "그리드"가있는 경우 :
select
size,
color
from
sizes CROSS JOIN colors
하루의 1 분마다 행이 포함 된 테이블을 원할 수 있으며이를 사용하여 프로 시저가 1 분마다 실행되었는지 확인하여 세 개의 테이블을 교차 할 수 있습니다.
select
hour,
minute
from
hours CROSS JOIN minutes
또는 연중 매월 적용 할 표준 보고서 사양 세트가 있습니다.
select
specId,
month
from
reports CROSS JOIN months
이들을 뷰로 유지하는 문제는 대부분의 경우 특히 옷과 관련하여 완전한 제품을 원하지 않는다는 것입니다. MINUS
쿼리에 논리를 추가 하여 가지고 있지 않은 특정 조합을 제거 할 수 있지만 다른 방법으로 테이블을 채우고 카티 전 곱을 사용하지 않는 것이 더 쉬울 수 있습니다.
또한 생각보다 행이 몇 개 더 많거나 WHERE
절이 부분적으로 또는 완전히 누락 된 테이블에서 교차 조인을 시도하게 될 수도 있습니다 . 이 경우 DBA는 누락 사실을 즉시 알려줄 것입니다. 보통 그 또는 그녀는 행복하지 않을 것입니다.
좋아요, 이것은 아마도 질문에 대답하지 않을 것입니다. 그러나 그것이 사실이라면 (그리고 나는 그것을 확신하지 못합니다) 그것은 재미있는 역사입니다.
Oracle 초기에 개발자 중 한 명이 테이블의 모든 행을 복제해야한다는 것을 깨달았습니다 (예 : 이벤트 테이블 일 수 있으며 "시작 이벤트"와 "종료 이벤트"를 별도로 변경해야 함). 항목). 그는 행이 두 개 뿐인 테이블이있는 경우 첫 번째 테이블의 열만 선택하여 크로스 조인을 수행 할 수 있다는 것을 깨달았습니다. 그래서 그는 자연스럽게 "DUAL"이라고 불리는 간단한 테이블을 만들었습니다.
나중에 작업 자체가 테이블과 관련이없는 경우에도 테이블에서 선택을 통해서만 수행 할 수있는 작업을 수행해야합니다 (아마도 시계를 잊고 SELECT SYSDATE FROM.를 통해 시간을 읽고 싶었을 것입니다. .) 그는 여전히 자신의 DUAL 테이블이 주변에 누워 있다는 것을 깨달았고 그것을 사용했습니다. 잠시 후 그는 시간이 두 번 인쇄되는 것을 보는 것에 지쳐 결국 행 중 하나를 삭제했습니다.
Oracle의 다른 사람들은 그의 테이블을 사용하기 시작했고 결국 표준 Oracle 설치에 포함하기로 결정했습니다.
하나의 행이 있다는 유일한 의미를 갖는 테이블이 "2"를 의미하는 이름을 갖는 이유를 설명합니다.
핵심은 "가능한 모든 조합 표시"입니다. 다른 계산 된 필드와 함께 사용하여 정렬 / 필터링했습니다.
예를 들어 차익 거래 (거래) 애플리케이션을 구축하고 있다고 가정합니다. 당신은 가격에 제품을 제공하는 판매자와 가격에 제품을 요구하는 구매자가 있습니다. 제품 키에 대해 교차 조인을 수행하고 (잠재적 인 구매자와 판매자를 일치시키기 위해) 비용과 가격 간의 스프레드를 계산 한 다음 desc를 정렬합니다. 이것은 당신 (중개자)에게 가장 수익성있는 거래를 실행하기 위해 제공합니다. 물론 거의 항상 다른 경계 필터 기준이 있습니다.
이것은 교차 조인을 사용하여 교차 분석 보고서 를 만드는 흥미로운 방법 입니다. Joe Celko의 SQL For Smarties 에서 발견했으며 여러 번 사용했습니다. 약간의 설정이 필요하지만 시간을 투자 할 가치가 있습니다.
당신은 그것을 사용할 수 있습니다 가입 CROSS 목적으로 테스트를위한 데이터를 생성 - - 모든 속성을 결합 - 당신이 예를 들어 혈액 그룹 (A, B, ...)의 모든 가능한 조합을 필요 Rh를 함께 - / +, 등등 ... :에 그것을 --tune 귀하의 목적을 위해;)-나는이 분야의 전문가가 아닙니다.)
CREATE TABLE "HR"."BL_GRP_01"
("GR_1" VARCHAR2(5 BYTE));
REM INSERTING into BL_GRP_01
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_01 (GR_1) values (NULL);
CREATE TABLE "HR"."BL_GRP_02"
("GR_1" VARCHAR2(5 BYTE));
REM INSERTING into BL_GRP_02
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_02 (GR_1) values (NULL);
CREATE TABLE "HR"."RH_VAL_01"
("RH_VAL" VARCHAR2(5 BYTE));
REM INSERTING into RH_VAL_01
SET DEFINE OFF;
Insert into RH_VAL_01 (RH_VAL) values ('+');
Insert into RH_VAL_01 (RH_VAL) values ('-');
Insert into RH_VAL_01 (RH_VAL) values (NULL);
select distinct a.GR_1 || b.GR_1 || c.RH_VAL as BL_GRP
from BL_GRP_01 a, BL_GRP_02 b, RH_VAL_01 c
GROUP BY a.GR_1, b.GR_1, c.RH_VAL;