#sql #sql-server #tsql #common-table-expression
#sql #sql-сервер #tsql #common-table-expression
Вопрос:
Я хочу взять результат запроса CTE и использовать его внутри другого запроса.
В этом упрощенном примере для возврата списка идентификаторов используется запрос CTE.
with test_cte (id,name) as (
select id, name
from test
)
select id
from test_cte
where name = 'john'
Я хочу использовать этот список идентификаторов для удаления некоторых подобных записей, но я получаю синтаксическую ошибку:
delete from test
where id in (
with test_cte (id,name) as (
select id, name
from test
)
select id
from test_cte
where name = 'john'
)
Есть ли способ сделать это?
Комментарии:
1. CTE определяется в начале вашего оператора, а не в середине.
2. Итак, я не могу использовать его как подзапрос, правильно?
3. Это не подзапрос, @Madison, это CTE (общее табличное выражение): С common_table_expression (Transact-SQL) . CTE всегда определяется в начале инструкции, как показано в связанной документации.
4. Да, я этого боялся.
5. Это не значит, что вы не можете использовать его в инструкции DML, @Madison320 , вы просто используете его неправильно…
Ответ №1:
Ты просто имеешь в виду это:
;with test_cte(id,name) as
(
select id,name from dbo.test
)
delete test_cte where name='john';
Вы хотите удалить строки и показать строки, которые вы удалили?
;with test_cte(id,name) as
(
select id,name from dbo.test
)
delete test_cte
output deleted.id, deleted.name
where name='john';
- Пример db<>скрипка
Чтобы взять ваш явный пример:
delete from test
where id in (
with test_cte (id,name) as (
select id, name
from test
)
select id
from test_cte
where name = 'john'
)
Вы получаете синтаксическую ошибку, потому что, ну, в вашем синтаксисе есть ошибка. CTE должен быть определен заранее, а не в какой-либо случайной или произвольной точке вашего запроса.
;with test_cte (id,name) as (
select id, name
from test
)
delete from test
where id in (
select id
from test_cte
where name = 'john'
)
Но это все еще кажется ужасно сложным по сравнению с более простыми примерами, которые я показал.
Комментарии:
1. Я должен признать, меня действительно все еще смущает, что вы находитесь на стороне того забора, который рассматривает точку с запятой как «beginninator».
2. @Larnu, потому что все равно скопирует и вставит это в процедуру, которая имеет
DECLARE @name varchar(32) = 'john'
, а затем кричит на меня, что я нарушил их код. Считайте это постоянным.3. Тогда, возможно, вам следует привести более репрезентативный пример, @Madison320 .
4. @ThomasDoconski Посмотрите ветку комментариев. Причина в том, что люди берут
WITH ...
образцы кода и вставляют его в свой существующий код без точек с запятой в предыдущих операторах. Затем нас обвиняют в том, что мы даем им плохой код. У вас может быть столько операторов с запятой до и после, сколько вы хотите, поэтому нет никакого вреда в том, чтобы изолировать себя от этого заранее, за исключением необходимости объяснять себя. Я начинаю задаваться вопросом, что хуже.5. В этом случае у @AaronBertrand есть очень веская точка зрения: вы задали неправильный вопрос, то есть вы слишком упростили, и, следовательно, лучший ответ на ваш вопрос не будет работать в вашем реальном случае использования…