2017-01-12 41 views
12

爲什麼即使SELECT缺少FROM這個SQL查詢也會工作,這將是一個語法錯誤。還請注意查詢只顯示滿足WHERE條款的查詢。如果語法錯誤,SQL Exists語句如何工作?

CREATE TABLE Customer_Tbl 
(
    CustomerName VARCHAR(50), 
    Address VARCHAR(250), 
    Country VARCHAR(50) 
); 


INSERT INTO Customer_Tbl 
VALUES 
    ('AAA', '','Philippines'), 
    ('BBB', '','Mexico'), 
    ('CCC', '','Philippines'), 
    ('DDD', '','Mexico'), 
    ('EEE', '','Philippines'); 


SELECT * 
FROM Customer_Tbl 
WHERE EXISTS(
    -- This is missing a FROM 
    -- running it by itself is a syntax error. 
    SELECT 2 Customer_Tbl 
    WHERE Country = 'MEXICO' 
); 

這是SQL Server上測試 2012年和2014年,這裏是一個在線樣本:http://rextester.com/GDGB80815

+9

基於錯誤假設的問題。實際上沒有語法錯誤時,產品不報告語法錯誤。 –

回答

28

在SQL Server內部不需要FROMSELECT聲明中。

例如,有在下面的查詢沒有語法錯誤:

SELECT 2 AS t 
WHERE 0 = 0 

它返回一個行與列t和值2

你可以寫簡單的

SELECT 2 AS t 

得到相同的結果。


您的查詢與此相同:

SELECT * 
FROM Customer_Tbl 
WHERE EXISTS(
    SELECT 2 AS Customer_Tbl 
    WHERE Customer_Tbl.Country = 'MEXICO' 
); 

Customer_Tbl是與不斷2列的別名。 WHERE中的Country是外表Customer_Tbl的列。

使用AS作爲別名並完全限定具有其表名的列是一種很好的做法。


當您嘗試運行內部部分分別

SELECT 2 Customer_Tbl 
WHERE Country = 'MEXICO' 

失敗不是因爲沒有FROM,但因爲分析器不知道什麼是Country

消息207,級別16,狀態1,行2無效的列名稱'國家'。


爲了完整起見,這裏是SQL Server SELECT語句的語法從MSDN

<SELECT statement> ::=  
    [ WITH { [ XMLNAMESPACES ,] [ <common_table_expression> [,...n] ] } ] 
    <query_expression> 
    [ ORDER BY { order_by_expression | column_position [ ASC | DESC ] } 
    [ ,...n ] ] 
    [ <FOR Clause>] 
    [ OPTION (<query_hint> [ ,...n ]) ] 
<query_expression> ::= 
    { <query_specification> | (<query_expression>) } 
    [ { UNION [ ALL ] | EXCEPT | INTERSECT } 
     <query_specification> | (<query_expression>) [...n ] ] 
<query_specification> ::= 
SELECT [ ALL | DISTINCT ] 
    [TOP (expression) [PERCENT] [ WITH TIES ] ] 
    <select_list> 
    [ INTO new_table ] 
    [ FROM { <table_source> } [ ,...n ] ] 
    [ WHERE <search_condition> ] 
    [ <GROUP BY> ] 
    [ HAVING <search_condition> ] 

可選的子句是在方括號[]。正如你所看到的,幾乎所有的子句都是可選的,包括FROM,除了SELECT關鍵字本身和<select_list>

5

它是有效的。它關聯回Customer_Tbl.Country

如果有至少一個記錄在Customer_Tbl.Country='MEXICO'那麼WHERE EXISTS是TRUE

I'ts唯一有效的當它的EXISTS雖然

+0

如果您嘗試使用'FROM Customer_Tbl'完成EXIST,它將輸出不同的結果 – jbalintac

+3

@jbalintac這是因爲當前您的聲明是將'Customer_Tbl'解釋爲列別名。如果你改變它(在Customer_Tbl之前添加'FROM'),它將把Customer_Tbl解釋爲一個表,並且存在的子句將完全不同。 – ZLK

+1

是的,當你添加'FROM Customer_Tbl'時,它不再與外部的Customer_Tbl相關聯,不管外部的'Customer_Tbl'中引用了什麼行,'EXIST'都是true,所以你得到所有的行 –