У меня есть эта схема тестирования:
CREATE TABLE A
(
ID INT PRIMARY KEY,
A VARCHAR(1),
B VARCHAR(3),
C VARCHAR(3),
BID INT,
DATE DATETIME2(7)
)
INSERT INTO A values
(1, NULL, 'AAA', 'XXX', 1, '2018-04-04'),
(2, NULL, 'BBB', 'YYY', 2, '2018-05-05'),
(3, NULL, 'CCC', 'ZZZ', 2, '2018-06-06')
CREATE TABLE B
(
ID INT PRIMARY KEY,
X VARCHAR(1),
Y VARCHAR(1),
Z VARCHAR(1)
)
INSERT INTO B values
(1, 'A', 'A', 'A'),
(2, 'B', 'B', 'B'),
(3, 'C', 'C', 'C'),
(4, 'D', 'D', 'D'),
(5, 'E', 'E', 'E')
CREATE TABLE C
(
ID INT PRIMARY KEY,
NAME VARCHAR(12)
)
INSERT INTO C values
(1, 'Mary'),
(2, 'John'),
(3, 'Peter')
CREATE TABLE D
(
ID INT PRIMARY KEY,
CID INT,
R VARCHAR(3),
S VARCHAR(3)
)
INSERT INTO D values
(1, 1, 'AAA', 'ABC'),
(2, 2, 'BBB', 'ZZZ'),
(3, 1, 'FOO', 'ZZZ'),
(4, 3, 'BAR', 'YYY')
И у меня есть этот запрос:
WITH T1 AS
(
SELECT A.ID, A.A, A.B, A.C, B.X, B.Y, B.Z
FROM A
LEFT JOIN B
ON A.BID = B.ID
WHERE A.DATE BETWEEN '2018-01-01' AND '2018-12-31'
)
(
SELECT T1.ID, T1.A, T1.B AS VALUE, T1.X, T1.Y, T1.Z, T2.NAME
FROM T1
LEFT JOIN
(
SELECT C.NAME, D.R
FROM C
INNER JOIN D
ON C.ID = D.CID
) AS T2
ON T1.B = T2.R
)
UNION ALL
(
SELECT T1.ID, T1.A, T1.C AS VALUE, T1.X, T1.Y, T1.Z, T2.NAME
FROM T1
LEFT JOIN
(
SELECT C.NAME, D.S
FROM C
INNER JOIN D
ON C.ID = D.CID
) AS T2
ON T1.C = T2.S
)
Скрипка здесь .
План выполнения можно найти в скрипке.
Глядя на текущий план выполнения, есть два дерева, ответвляющиеся от объединения. Оба дерева практически идентичны. Это означает, что запрос внутри T1
был выполнен дважды из-за UNION ALL
. Можно ли как-нибудь переписать это, возможно, заменив UNION ALL
на JOIN
?
P.S. Отредактированный вопрос со схемой теста и скрипкой.