Пропуск инструкции FROM
не указан c для CROSS
/ OUTER
APPLY
; любое допустимое SQL предложение select может его опустить. Если вы не используете FROM, у вас нет источника данных, поэтому вы не можете указать столбцы в этом источнике. Скорее вы можете выбрать только те значения, которые уже существуют; будь то константы, определенные в самом операторе или в некоторых случаях (например, в подзапросах) столбцов, на которые ссылаются другие части запроса.
Это проще понять, если вы знакомы с Oracle 's Dual
Таблица; стол с 1 строкой. В MS SQL эта таблица будет выглядеть следующим образом:
-- Ref: https://blog.sqlauthority.com/2010/07/20/sql-server-select-from-dual-dual-equivalent/
CREATE TABLE DUAL
(
DUMMY VARCHAR(1) NOT NULL
, CONSTRAINT CHK_ColumnD_DocExc CHECK (DUMMY = 'X') -- ensure this column can only hold the value X
, CONSTRAINT PK_DUAL PRIMARY KEY (DUMMY) -- ensure we can only have unique values... combined with the above means we can only ever have 1 row
)
GO
INSERT INTO DUAL (DUMMY)
VALUES ('X')
GO
Затем вы можете сделать select 1 one, 'something else' two from dual
. Вы на самом деле не используете двойной; просто убедитесь, что у вас есть таблица, которая всегда будет возвращать ровно 1 строку.
Теперь в SQL, где бы вы ни пропускали оператор FROM
, считайте этот оператор таким, как если бы он сказал FROM DUAL
/ он имеет то же значение , только SQL допускает такой более краткий подход.
Обновление
Вы упоминаете в комментариях, что не видите, как вы можете ссылаться на столбцы из исходного оператора в подзапросе (например, того типа, который вы можете увидеть при использовании APPLY
). Приведенный ниже код показывает это без сценария APPLY
. По общему признанию, демонстрационный код здесь не тот, который вы когда-либо использовали (поскольку вы могли бы просто набрать where Something like '%o%'
в исходном операторе, не нуждаясь в выражении подзапроса / in), но в иллюстративных целях он показывает точно такой же сценарий, что и вы. получил с вашим сценарием APPLY; то есть оператор просто возвращает значение SOMETHING
для текущей строки.
declare @someTable table (
Id bigint not null identity(1,1)
, Something nvarchar(32) not null
)
insert @someTable (Something) values ('one'), ('two'), ('three')
select *
from @someTable x
where x.Something in
(
-- this subquery references the SOMETHING column from above, but doesn't have a FROM statement
-- note: there is only 1 value at a time for something here; not all 3 values at once; it's the same single value as Something as we have before the in keyword above
select Something
where Something like '%o%'
)