4

私は2つのテーブルを持っています:

顧客テーブル:

siteid nvarchar(2) PRIMARY KEY,
custid int PRIMARY KEY,
fname varchar(30),
lname varchar(30)

子供の表:

childid1 nvarchar(2) PRIMARY KEY,
childid2 int PRIMARY KEY,
siteid nvarchar(2),
custid int,
lname varchar(30),
lname varchar(30),
FOREIGN KEY(siteid)REFERENCES Cust(siteid),
FOREIGN KEY(custid)REFERENCES Cust(custid)

値:

お客様:

siteid | custid | fname | lname
A1     | 1111   | John  | S
A2     | 1111   | Steve | H
B1     | 2222   | Paul  | N
C3     | 3333   | Mary  | J

子供:

childid1 | childid2 | siteid | custid | fname | lname
A6       | 1010     | A1     | 1111   | Lisa  | S
A8       | 1011     | A1     | 1111   | Linda | S
A9       | 1012     | A1     | 1111   | Jose  | S
D9       | 1013     | A2     | 1111   | Jake  | H
D1       | 1014     | B1     | 2222   | Judy  | N
D1       | 1015     | B1     | 2222   | Judy  | N

私は子供のいない Cust を探しています。これが私のクエリです。

SELECT * FROM Cust WHERE Cust.siteid NOT IN(
SELECT Children.siteid FROM Children
) AND Cust.custid NOT IN(
SELECT Children.custid FROM Children
)

しかし、結果は空になりました。テーブルには複合主キーがあるため、ここで正しいクエリは何でしょうか?

4

2 に答える 2

4

テーブルには 2 つの主キーがありません。一部には複合主キーがあり、これはここに当てはまるようです。Custテーブルに次の(siteid, custid)ようなものがある場合PRIMARY KEY:

CREATE TABLE Cust
( siteid nvarchar(2),
  custid int,
  fname varchar(30),
  lname varchar(30),
  PRIMARY KEY (siteid, custid)              -- one primary key
) ;

次に、外部キーの定義が間違っています。(複合) 主キーを参照する 1 つの (複合) 外部キーが必要です。

CREATE TABLE Children
( childid1 nvarchar(2),
  childid2 int,
  siteid nvarchar(2),
  custid int,
  fname varchar(30),
  lname varchar(30),
  PRIMARY KEY (childid1, childid2),
  FOREIGN KEY (siteid, custid)               -- one foreign key 
    REFERENCES Cust(siteid, custid)
) ;

次に、クエリを記述する 1 つの方法は次のようになります (訂正: これは ANSI SQL であり、他の DBMS では機能しますが、SQL サーバーでは機能しません)。

SELECT * 
FROM Cust 
WHERE (siteid, custid) NOT IN
      ( SELECT siteid, custid  
        FROM Children
      ) ;

または、バージョンが予期しない結果を表示する可能性のある値NOT EXISTSの落とし穴を回避するため(SQL-Server では NOT IN が機能しないため、2 つ目:)NULLNOT IN

SELECT * 
FROM Cust AS c
WHERE NOT EXISTS
      ( SELECT * 
        FROM Children AS ch
        WHERE ch.siteid = c.siteid
          AND ch.custid = c.custid
      ) ;

SQLフィドルでテスト済み

于 2013-05-27T19:14:28.163 に答える