2016-11-02 15 views
2

を使用できます:INSERT INTOは、次のコマンドを実行すると、SELECTが存在しない列

CREATE TABLE TableA 
(
    A1 INT, 
    A2 INT 
) 

INSERT INTO TableA (A1, A2) VALUES (1, 2), (3, 4); 

CREATE TABLE #TempTable1 (ColumnA INT, ColumnB INT); 
CREATE TABLE #TempTable2 (ColumnA INT, ColumnB INT); 

INSERT INTO #TempTable1 (ColumnA, ColumnB) VALUES (1, 2); 

INSERT INTO #TempTable2 
    SELECT A1, A2 
    FROM TableA 
    WHERE A1 IN (SELECT ColumnA FROM #TempTable1); 

SELECT * FROM TableA; 
SELECT * FROM #TempTable1; 
SELECT * FROM #TempTable2; 

次のような結果は次のとおりです。

TableA 
A1 A2 
1 2 
3 4 

#TempTable1 
ColumnA ColumnB 
1  2 

#TempTable2 
ColumnA ColumnB 
1  2 

をしかし、私は#のTempTable2 INSERT文を変更した場合、それように、 #TempTable1から存在しない列A1を選択:

INSERT INTO #TempTable2 
    SELECT A1, A2 
    FROM TableA 
    WHERE A1 IN (SELECT A1 FROM #TempTable1); 

その後#TempTable2はTableAのすべてのデータが含まれています:

ColumnA ColumnB 
1  2 
3  4 

#TempTable1に列A1が存在しないため、INSERTステートメントの実行でエラーが発生しないのはなぜかと思います。私は、次のステートメントを追加しようとした場合たとえば、:

SELECT A1 FROM #TempTable1; 

を私が取得:

Invalid column name 'A1'. 

答えて

3

correlated sub-queryと呼ばれます。内部の外部クエリ列を参照するSub-Query

A1は、外部クエリ(つまりTableA)から参照されます。だから、あなたが一緒にクエリを実行すると、それが働いていると、あなたは一人で実行したときにwhere句に相関することになるEXISTS/NOT EXISTSクエリを使用する場合には、通常

SELECT A1, A2 
FROM TableA A 
WHERE A1 IN (SELECT A.A1 -- Here check the alias A 
      FROM #TempTable1); 

として

それは解釈されますが機能していません。あなたの例では

select * from tableA A 
where exists (select 1 from tableB B 
       where A.Id = B.Id -- A.Id is referred from tableA 
      ) 

あなたはあなたが結果を得るなぜ他の答えが既に答えている間、それがSelect

1
INSERT INTO #TempTable2 
    SELECT A1, A2 
    FROM TableA 
    WHERE A1 IN (SELECT A1 FROM #TempTable1); 

このクエリSELECT A1 FROM #TempTable1でサブクエリです。 A1は#TempTable1には見つかりませんが、TableAの各行のサブクエリとして使用するため、A1は上位テーブルから取られた値として認識されます。 A1はサブクエリの実行ごとに一定の値なので、サブクエリはWHERE 1 IN (SELECT 1 FROM #TempTable1);に相当します。

2

に呼ばれ、私がカバーし、この価値へのもう一つの側面があると思う:これは非常に良い例です。なぜあなたはテーブルエイリアスを使うべきですか?

あなたは、あなたが期待していたエラー受けているだろう、次のようにコードをエイリアスしていた場合は、次の別名がなけれ

INSERT INTO #TempTable2 
    SELECT a.A1, a.A2 
    FROM TableA a 
    WHERE a.A1 IN (SELECT t.A1 FROM #TempTable1 t); 

を、SQL Serverの(および他のDBMS製品が)喜んで一致した一つの列にデフォルト設定されますあなたが与えた名前。これは、人々があなたがやったこととまったく同じことをする間違いにつながりますが、問題に気付かないことになります。エイリアスを使用すると、エラーが表示され、問題が発生したことを確認して修正するだけです。