2017-01-12 81 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,所以你得到所有的行 –