プログラムの事とか

お約束ですが「掲載内容は私個人の見解です」

SQLの副問い合わせで手抜きをすると痛い目を見る罠

本職ではないですがRDBの扱いは初心者は卒業したくらいの私です

今回はSQL Server 15.0.*を使っていてはまった罠について (バージョンは関係ないかな)

準備

ABというテーブルを作ります

CREATE TABLE [dbo].[A](
    [ID] [int] NOT NULL,
    [BID] [int] NOT NULL,
 CONSTRAINT [PK_A] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[B](
    [BID] [int] NOT NULL,
    [TYPE] [int] NULL,
 CONSTRAINT [PK_B] PRIMARY KEY CLUSTERED 
(
    [BID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

リレーションは面倒なので貼っていませんが、A.BIDとB.BIDが外部参照しているつもりになってください

テーブル作ったら適当にデータ突っ込みます

A

f:id:puni-o:20210512133827p:plain

B

f:id:puni-o:20210512133801p:plain

副問い合わせあるいはサブクエリー

AのデータのうちBTYPEが0のものだけ検索します

select * from A where BID in (select BID from B where TYPE = 0)

f:id:puni-o:20210512134214p:plain

SQL文の中で一番好きなのが inです。目的のものが検索できていますね

間違えてみる

ABカラム名が紛らわしいので間違えてしまいました

select * from A where BID in (select ID from B where TYPE = 0)

f:id:puni-o:20210512134515p:plain

select ID from B where TYPE = 0IDが間違いで、これ単体で実行すると

f:id:puni-o:20210512134620p:plain

となるんですが、副問い合わせの場合A.IDを参照するみたいです (よくわかりません)

まとめ

上記のような間違いを起こさないようにカラムの指定はちゃんと書きましょう

select * from A where A.BID in (select B.BID from B where B.TYPE =0)

おしまい