FKにはNULLが入れれる

恥ずかしながら「FKにNULLって入れれたっけ?」というとこが分からなくなったので、調べてみた。

ドキュメントを見る限りOracleではアリで、SQL的にもアリの模様。

つーことで実際に確かめてみた。環境はSQLServer2005。

CREATE DATABASE TESTDB;
GO
USE TESTDB;
GO
CREATE TABLE PARENT(
       ID int PRIMARY KEY,
       VAL nvarchar(100)
);
GO
CREATE TABLE CHILD(
       ID int PRIMARY KEY,
       FKID int CONSTRAINT FK_PARENT_ID REFERENCES PARENT(ID),
       VAL nvarchar(100)
)
GO
INSERT INTO PARENT (ID, VAL) VALUES (1, ‘TEST1’);
INSERT INTO PARENT (ID, VAL) VALUES (2, ‘TEST2’);
INSERT INTO PARENT (ID, VAL) VALUES (3, ‘TEST3’);
INSERT INTO PARENT (ID, VAL) VALUES (4, ‘TEST4’);
INSERT INTO PARENT (ID, VAL) VALUES (5, ‘TEST5’);
GO
INSERT INTO CHILD (ID,FKID,VAL) VALUES (1,1,’test1′);
INSERT INTO CHILD (ID,FKID,VAL) VALUES (2,2,’test2′);
INSERT INTO CHILD (ID,FKID,VAL) VALUES (3,3,’test3′);
INSERT INTO CHILD (ID,FKID,VAL) VALUES (4,4,’test4′);
INSERT INTO CHILD (ID,FKID,VAL) VALUES (5,5,’test5′);
INSERT INTO CHILD (ID,FKID,VAL) VALUES (6,NULL,’test6′);

で、DBの回答

SELECT * FROM CHILD
       INNER JOIN PARENT ON (CHILD.FKID=PARENT.ID);

1       1       test1   1       TEST1
2       2       test2   2       TEST2
3       3       test3   3       TEST3
4       4       test4   4       TEST4
5       5       test5   5       TEST5

SELECT * FROM CHILD
       LEFT OUTER JOIN PARENT ON (CHILD.FKID=PARENT.ID);
1       1       test1   1       TEST1
2       2       test2   2       TEST2
3       3       test3   3       TEST3
4       4       test4   4       TEST4
5       5       test5   5       TEST5
6       NULL    test6   NULL    NULL

当然の結果。

とはいえ、FKのカラムに対してはINNER JOINでよいというわけではないことに注意が必要ではある。
FKかつNOT NULLのカラムはINNER JOINでよいけれども、NOT NULL制約がない場合にはNULL列が落ちてしまうのだから。

コメントを残す