#sql #sql-server
#sql #sql-сервер
Вопрос:
Я пытаюсь решить проблему с командировками и пользователями SQL Leetcode. Если я правильно читаю, NOT IN
cte не работает, но NOT IN
подзапрос работает. Почему?
Работает следующий код.
select request_at as Day,
cast(sum(iif(status like 'cancelled%', 1.0, 0.0))/count(status) as decimal(4,2)) as [Cancellation Rate]
from trips
where (request_at between '2013-10-01' and '2013-10-03')
and client_id not in (SELECT USERS_ID FROM USERS WHERE BANNED='Yes')
and driver_id not in (SELECT USERS_ID FROM USERS WHERE BANNED='Yes')
group by request_at
Но приведенный ниже не работает. Я получаю сообщение об ошибке:
Runtime Error
[42000] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Incorrect syntax near 'BANNED_USRS'. (102) (SQLExecDirectW)
with
banned_usrs as
(select users_id from users where banned = 'Yes')
select request_at as Day,
cast(sum(iif(status like 'cancelled%', 1.0, 0.0))/count(status) as decimal(4,2)) as [Cancellation Rate]
from trips
where (request_at between '2013-10-01' and '2013-10-03')
and client_id not in banned_usrs
and driver_id not in banned_usrs
group by request_at
Комментарии:
1. banned_usrs — это таблица в вашем cte. Если вы попытаетесь присоединиться к banne_usrs, а затем выполнить фильтрацию после присоединения, это будет иметь смысл.
2. Как объяснялось, CTE — это виртуальная таблица , а не подзапрос. Вы не можете использовать формат, подобный «in имя_таблицы», поскольку таблица может иметь несколько столбцов, и нет встроенного синтаксиса для проверки наличия значения во всех строках и во всех столбцах таблицы. Синтаксис, который вы должны использовать, примерно такой: »
in (select column_Name From Table_Name)
»3. Ооо … спасибо!
Ответ №1:
Вам нужно явно выбрать из CTE:
with banned_usrs as (select users_id from users where banned = 'Yes')
select
request_at as Day,
cast(sum(iif(status like 'cancelled%', 1.0, 0.0))/count(status) as decimal(4,2)) as [Cancellation Rate]
from trips
where
request_at between '2013-10-01' and '2013-10-03' and
client_id not in (select users_id from banned_usrs) and
driver_id not in (select users_id from banned_usrs);
group by
request_at;
CTE сам по себе является просто кодом SQL и не формирует подзапрос, если вы явно не пишете его как таковой.