Поместите дополнительный предикат t1.p=
в каждое левое соединение, чтобы они стали взаимоисключающими по мере необходимости для результата.Это позволило бы использовать coalesce
вместо выражения case (но с выражением case все в порядке, это просто опция).
Нет убедительной причины использовать оператор применения в вашем примере, и хотя они оптимизируют лучше, чем коррелированные подзапросы, помещенные в предложение select, они остаются коррелированными подзапросами.На мой взгляд, если нет веской причины для «более экзотического» варианта, не используйте его.Так что не используйте здесь оператор применения, перейдите к более стандартному левому соединению.
SELECT
t1.a
, COALESCE(t2.g,t3.g) AS v
FROM t1
LEFT JOIN t2 ON t1.x = t2.x AND t1.p = 1
LEFT JOIN t3 ON t1.y = t3.y AND t1.p = 2
;
Если, однако, у вас была функциональная потребность в одной (или предписанном количестве) строк из этих коррелированных подзапросов затем у вас будет веская причина использовать заявку, например
SELECT
t1.a
, t2.v
FROM t1
OUTER APPLY (
SELECT
CASE
WHEN t1.p = 1 THEN (
SELECT TOP(1) t2.g FROM t2 -- top
WHERE t1.x = t2.x
ORDER BY t2.z -- order
)
WHEN t1.p = 2 THEN (
SELECT TOP(1) t3.g FROM t3 -- top
WHERE t1.y = t3.y
ORDER BY t3.z -- order
)
END AS v
) t2
Независимо от мнения, использование планов выполнения - лучший способ для сравнения параметров запроса.