Oracle에서 버그라고 생각되는 것을 발견했습니다. 그러나 내가 놓친 문서가 있는지 궁금합니다.테이블에 종속 된 뷰에 테이블을 결합 할 때 Oracle에서의 버그입니까?
바이올린 : 오라클 : http://sqlfiddle.com/#!4/43c19/2 SQL 서버 : http://sqlfiddle.com/#!3/ddc49/1 MySQL의 : http://sqlfiddle.com/#!2/43c195/1
기본적으로 내가 보조 테이블에 조인 왼쪽 기본 테이블이있다. 그 다음 나는 전망에 합류했다. 보조 테이블의 열이 null이 아닐 때 조인하려는 뷰에 조인을 지정하면 예기치 않은 결과가 발생합니다. 이것은 쿼리를 보여줌으로써 가장 잘 설명됩니다 :
SELECT
1,
MainTable.*
FROM
MainTable
LEFT JOIN SecondaryTable ON MainTable.KeyColumn = SecondaryTable.KeyColumn
LEFT JOIN ViewWithoutSecondary ON ((SecondaryTable.KeyColumn IS NOT NULL) AND SecondaryTable.KeyColumn = ViewWithoutSecondary.KeyColumn)
UNION ALL
SELECT
2,
MainTable.*
FROM
MainTable
LEFT JOIN SecondaryTable ON MainTable.KeyColumn = SecondaryTable.KeyColumn
LEFT JOIN ViewWithSecondary ON ((SecondaryTable.KeyColumn IS NOT NULL) AND SecondaryTable.KeyColumn = ViewWithSecondary.KeyColumn)
직접 테스트 스크립트를 작성하려면 아래를 참조하십시오. SQL Server와 MySql에서 동일한 결과를 얻지 만 Oracle은 다릅니다. 스키마에는 3 개의 테이블과 2 개의 뷰가 있습니다.
오라클에서CREATE VIEW ViewWithoutSecondary
AS
SELECT
TertiaryTable.KeyColumn,
TertiaryValue + 1 ViewValue
FROM
TertiaryTable
CREATE VIEW ViewWithSecondary
AS
SELECT
SecondaryTable.KeyColumn,
TertiaryValue + 1 ViewValue
FROM
SecondaryTable
LEFT JOIN TertiaryTable ON SecondaryTable.KeyColumn = TertiaryTable.KeyColumn;
, 내가보기 SecondaryTable에 대한 참조를 포함하는 경우, 그때는 보조 테이블에서 일치를 MainTable에서 행을 얻을 것으로 나타났습니다 다음과 같이 뷰가 정의되어 있습니다. 오라클이 뷰 코드를 어떤 식 으로든 인라인하여 행 중 하나가 생략 된 것처럼 보입니다.
MainTable에 세 개의 행이 있다면 두 개의 왼쪽 조인을 수행 할 때 적어도 세 개의 행과 항상 조인의 결과를 반환해야한다고 생각합니다. 그러나 주어진 예에서는 그렇지 않습니다.
값이 null 인 경우 절의 후반부가 true가 아니기 때문에 SecondaryTable.KeyValue IS NOT NULL
이 중복되는 것을 알고 있지만 최적화 프로그램이 더 좋은 계획을 세울 수 있도록 쿼리를 다시 작성하려고했습니다.
예제를 실행하기 위해 전체 작성 스크립트는 다음과 같습니다 당신이이 쿼리 계획을 설명 실행하면
CREATE TABLE MainTable
(
KeyColumn varchar(32),
ValueColumn varchar(32)
);
INSERT INTO MainTable VALUES ('123', 'abc');
INSERT INTO MainTable VALUES ('456', 'def');
INSERT INTO MainTable VALUES ('789', 'ghi');
CREATE TABLE SecondaryTable
(
KeyColumn varchar(32),
SecondaryValue integer
);
INSERT INTO SecondaryTable VALUES ('123', 1);
INSERT INTO SecondaryTable VALUES ('456', 2);
CREATE TABLE TertiaryTable
(
KeyColumn varchar(32),
TertiaryValue integer
);
INSERT INTO TertiaryTable VALUES ('123', 1);
CREATE VIEW ViewWithoutSecondary
AS
SELECT
TertiaryTable.KeyColumn,
TertiaryValue + 1 ViewValue
FROM
TertiaryTable;
CREATE VIEW ViewWithSecondary
AS
SELECT
SecondaryTable.KeyColumn,
TertiaryValue + 1 ViewValue
FROM
SecondaryTable
LEFT JOIN TertiaryTable ON SecondaryTable.KeyColumn = TertiaryTable.KeyColumn;
Mimer SQL은 MySQL과 동일한 결과를 얻습니다. – jarlh
그래서 DB 엔진은 MySQL, SQL Server 또는 Oracle입니까? 세 개의 태그가 모두 있습니다 –
나는 이것이 버그 여야합니다 동의합니다. 필자는 Oracle 10.2를 사용해 보았습니다. 한 행 누락과 같은 결과를 얻었습니다. MySQL과 SQL Server는 올바르게 작동하지만 Oracle은 그렇지 않습니다. –