大文字と小文字の区別に依存しないものを使用して何が起こっているかを説明しましょう。
USE tempdb;
GO
CREATE TABLE dbo.main_table(column1 INT);
CREATE TABLE dbo.other_table(column2 INT);
INSERT dbo.main_table SELECT 1 UNION ALL SELECT 2;
INSERT dbo.other_table SELECT 1 UNION ALL SELECT 3;
SELECT column1 FROM dbo.main_table
WHERE column1 IN (SELECT column1 FROM dbo.other_table);
結果:
column1
-------
1
2
なぜそれはエラーを引き起こさないのですか?SQL Serverはクエリを調べて、内部のcolumn1がother_tableに存在しない可能性があることを確認しているため、外部参照テーブルに存在するcolumn1を推定して「使用」しています(テーブル参照のない外部テーブル)。このバリエーションについて考えてみてください。
SELECT [column1] FROM dbo.main_table
WHERE EXISTS (SELECT [column1] FROM dbo.other_table WHERE [column2] = [column1]);
結果:
column1
-------
1
ここでも、SQL Serverは、where句のcolumn1もローカルで参照されるテーブルに存在しないことを認識していますが、外部スコープでそれを見つけようとします。したがって、架空の世界では、クエリが実際に次のように言っていると考えるかもしれません。
SELECT m.[column1] FROM dbo.main_table AS m
WHERE EXISTS (SELECT m.[column1] FROM dbo.other_table AS o WHERE o.[column2] = m.[column1]);
(これは私が入力した方法ではありませんが、そのように入力した場合でも機能します。)
論理的に意味をなさない場合もありますが、これはクエリエンジンが行う方法であり、ルールを一貫して適用する必要があります。あなたの場合(しゃれは意図されていません)、さらに複雑な問題があります:大文字と小文字の区別。SQL ServerはFIELD
サブクエリで見つかりませんでしたが、外部クエリでは見つかりました。だからいくつかのレッスン:
- 列参照の前には常にテーブル名またはエイリアスを付けてください(また、テーブル参照の前には常にスキーマを付けてください)。
- 常に大文字と小文字を区別して、テーブル、列、その他のエンティティを作成して参照してください。特に、バイナリまたは大文字と小文字を区別する照合を使用する場合。