Удалить дублированный подзапрос
У меня сложный SQL-запрос, который можно упростить до следующего:
Select ColA,ColB,ColC,ColD
From MyTable
Where (ColA In (Select ItemID From Items Where ItemName like '%xxx%')
or ColB In (Select ItemID From Items Where ItemName like '%xxx%'))
Как вы можете видеть, суб-запрос появляется дважды. Является ли компилятор достаточно интеллектуальным для обнаружения этого и получает результат подзапроса только один раз? Или второй запрос выполняется дважды?
FYI, элементы таблицы содержат около 20 000 строк, а MyTable имеет около 200 000 строк.
Есть ли другой способ перезаписать этот оператор SQL, чтобы подзапрос появлялся/запускался только один раз?
Обновление: предложение Where в основном запросе является динамическим и добавляется только при необходимости (т.е. только когда пользователь ищет "xxx" ). Следовательно, изменения в операторе основного выбора или реструктуризации запроса невозможны.
Ответы
Ответ 1
ОБНОВЛЕНИЕ Ваш запрос не изменять запрос, просто WHERE
Вы можете упаковать CTE непосредственно в том месте, где оно называется (непроверено):
Select ColA,ColB,ColC,ColD
From MyTable
Where EXISTS (SELECT 1 FROM (Select i.ItemID
From Items AS i
Where iItemName like '%xxx%') AS itm
WHERE itm.ItemID=MyTable.ColA OR itm.ItemID=MyTable.ColB)
предыдущая
Я думаю, что это должно быть одно и то же...
WITH MyCTE AS
(
Select ItemID From Items Where ItemName like '%xxx%'
)
Select ColA,ColB,ColC,ColD
From MyTable
Where EXISTS (SELECT 1 FROM MyCTE WHERE ItemID=ColA OR ItemID=ColB)
Подстрока LIKE
поиск - наверняка - не работает.
Если вы можете уменьшить свои "Items" до нескольких строк с помощью фильтра LIKE
, вы должны проверить, что быстрее.
Ответ 2
Вы также можете написать запрос следующим образом:
SELECT ColA, ColB, ColC, ColD
FROM MyTable
WHERE EXISTS(
(SELECT ItemID FROM Items WHERE ItemName LIKE '%xxx%')
INTERSECT
SELECT t.v FROM (VALUES (ColA), (ColB)) AS t(v) )
Ответ 3
Нет гарантии, что он будет следовать фактическому порядку исполнения. Это зависит от того, как вы пишете запрос. Идентичные подзапросы обычно выполняются только один раз.
В стандартном SQL существует предложение WITH
.
WITH mySubQuery AS
(
[the subquery code]
)
SELECT * FROM
mySubQuery AS sq
WHERE xyz IN (mySubQuery)
Ответ 4
SQL-программисты могут использовать CTE (Common Table Expression) в таких случаях
Вы можете определить CTE с использованием подзапроса один раз и использовать его в инструкции SQL, ссылаясь более одного раза.
Обратитесь к учебному курсу SQL CTE Common Table Expression для образцов
CTE - очень мощные инструменты для разработчиков SQL, особенно при использовании в качестве рекурсивных запросов