2017-01-12 2 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がFROMを必要としませんが、それはEXISTS内だときにのみ有効I'ts TRUEです

少なくとも1つのレコードがCustomer_Tbl.Country='MEXICO'であった場合、その後WHERE EXISTSをバックCustomer_Tbl.Country

に相関ますSELECTステートメントの

例えば、何構文エラーは、次のクエリではありません:

SELECT 2 AS t 
WHERE 0 = 0 

これはカラムt2と一列を返します。

あなたは同じ結果を得るために、簡単な

SELECT 2 AS t 

を書くことができます。


あなたのクエリはこれと同じである:

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

インナーCustomer_Tblが一定2と列の別名です。 WHERECountryは、外側の表Customer_Tblの列です。

エイリアスにASを使用し、テーブル名で列を完全修飾することをお勧めします。


あなたは別途

SELECT 2 Customer_Tbl 
WHERE Country = 'MEXICO' 

FROMがないので、それはない失敗しますが、パーサはCountryが何であるかを知らないため、内側の部分を実行しよう:

メッセージ207、レベル16、状態1、行2無効な列名 '国'。完全を期すために


、ここMSDNからSQL Server内のSELECT文の構文は次のとおりです。

<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> ] 

オプションの句は、角括弧[]です。ご覧のとおり、(SELECTというキーワード自体と<select_list>を除く)を含むほぼすべての節はオプションです。

5

それが有効です。

+0

EXISTを 'FROM Customer_Tbl'で完了しようとすると、別の結果が出力されます – jbalintac

+3

@jbalintacこれは、現在のステートメントでは' Customer_Tbl'を列エイリアスとして解釈しているからです。これを変更すると( 'Customer_Tbl'の前に' FROM'を追加すると) 'Customer_Tbl'がテーブルとして解釈され、exists節は完全に異なったものになります。 – ZLK

+1

はい 'FROM Customer_Tbl'を追加すると、外部の' Customer_Tbl'にはもはや相関関係がなくなります。 'EXIST'は外部' Customer_Tbl'でどの行が参照されているかに関係なく常に真です。 –

関連する問題