我用两个表创建了一个数据库。首先是PERSON,其次是REFEREES。
这是代码:
CREATE TABLE Person(
PersonID serial,
CONSTRAINT PK_Person PRIMARY KEY(PersonID),
FirstName VARCHAR(20),
LastName VARCHAR(30));
CREATE TABLE Referees(
RefereePairID SERIAL,
CONSTRAINT PK_Referee PRIMARY KEY(RefereePairID),
Referee1ID int,
Referee2ID int);
ALTER TABLE Referees
ADD CONSTRAINT FK_Referee1 FOREIGN KEY(Referee1ID) references Person(PersonID);
ALTER TABLE Referees
ADD CONSTRAINT FK_Referee2 FOREIGN KEY(Referee1ID) references Person(PersonID);
INSERT INTO Person VALUES (DEFAULT, 'AAAAAA', 'AAAAAA');
INSERT INTO Person VALUES (DEFAULT, 'BBBBBB', 'BBBBBB');
INSERT INTO Person VALUES (DEFAULT, 'CCCCCC', 'CCCCCC');
INSERT INTO Person VALUES (DEFAULT, 'DDDDDD', 'DDDDDD');
INSERT INTO Referees VALUES (DEFAULT, 1, 2);
INSERT INTO Referees VALUES (DEFAULT, 3, 4);
我期望的下一个查询的输出:
SELECT * FROM Person, Referees WHERE Referees.RefereePairID = 1;
PersonID |FirstName|LastName|RefereePairID|Referee1ID|Referee2ID
---------+---------+--------+-------------+----------+----------
1 | AAAAAA | AAAAAA | 1 | 1 | 2
2 | BBBBBB | BBBBBB | 1 | 1 | 2
但问题是输出是这样的:
PersonID |FirstName|LastName|RefereePairID|Referee1ID|Referee2ID
---------+---------+--------+-------------+----------+----------
1 | AAAAAA | AAAAAA | 1 | 1 | 2
2 | BBBBBB | BBBBBB | 1 | 1 | 2
3 | CCCCCC | CCCCCC | 1 | 1 | 2
4 | DDDDDD | DDDDDD | 1 | 1 | 2
此外,当我输入下一个查询时,我得到以下结果:
SELECT * FROM Referees WHERE Referees.RefereePairID = 1;
RefereePairID | Referee1ID | Referee2ID
---------------+------------+------------
1 | 1 | 2
有谁知道问题出在哪里?因为我没理解:(
答案 0 :(得分:1)
您的FK定义以及SQL中都有错误。
这是一个有效的SQLFiddle ,修复了这两个问题并返回了您期望的数据集:http://sqlfiddle.com/#!15/b7141/1
您的第二个外键定义也指RefereeID1
而不是RefereeID2
。
所以修改那个定义就像这样
ALTER TABLE Referees
ADD CONSTRAINT FK_Referee2 FOREIGN KEY(Referee2ID) references Person(PersonID);
此外,您的SQL不正确。这是正确的SQL。
SELECT * FROM Person
JOIN Referees
ON Person.PersonID = Referees.Referee1ID
OR Person.PersonID = Referees.Referee2ID
WHERE Referees.RefereePairID = 1
答案 1 :(得分:1)
在第一个语句中,我猜你想根据它们的关系连接表,所以查询应该看起来与此类似:
SELECT * FROM Person
JOIN Referees
ON Person.PersonID = Referees.Referee1ID
OR Person.PersonID = Referees.Referee2ID
WHERE Referees.RefereePairID = 1
如果出于某种原因,您不想使用JOIN
,则可以将这些其他匹配条件传递给WHERE
:
SELECT *
FROM Person, Referees
WHERE (Person.PersonID = Referees.Referee1ID OR Person.PersonID = Referees.Referee2ID)
AND Referees.RefereePairID = 1
问题是,你必须在你的SQL语句中写下你想如何匹配表之间的记录。您已经定义了外键,但是当您从SQL语句中的多个表中进行选择时,它们不会为您提供自动匹配。
我还没有对这些SQL语句进行测试,因此它们可能包含错误。
此外,如另一个答案中所述,您还应该纠正其中一个约束。
答案 2 :(得分:1)
当你这样做时
SELECT *
FROM Person, Referees
表之间会发生笛卡尔积。这与
相同SELECT *
FROM Person CROSS JOIN Referees;
你得到:
+----------+-----------+----------+---------------+------------+------------+
| PersonID | FirstName | LastName | RefereePairID | Referee1ID | Referee2ID |
+----------+-----------+----------+---------------+------------+------------+
| 1 | AAAAAA | AAAAAA | 1 | 1 | 2 |
| 1 | AAAAAA | AAAAAA | 2 | 3 | 4 |
| 2 | BBBBBB | BBBBBB | 1 | 1 | 2 |
| 2 | BBBBBB | BBBBBB | 2 | 3 | 4 |
| 3 | CCCCCC | CCCCCC | 1 | 1 | 2 |
| 3 | CCCCCC | CCCCCC | 2 | 3 | 4 |
| 4 | DDDDDD | DDDDDD | 1 | 1 | 2 |
| 4 | DDDDDD | DDDDDD | 2 | 3 | 4 |
+----------+-----------+----------+---------------+------------+------------+
你需要添加一个像这样的额外条件
SELECT *
FROM Person, Referees
WHERE Referees.RefereePairID = 1
AND (Referees.Referee1ID = Person.PersonId OR Referees.Referee2ID = Person.PersonId);
获得预期结果
+----------+-----------+----------+---------------+------------+------------+
| PersonID | FirstName | LastName | RefereePairID | Referee1ID | Referee2ID |
+----------+-----------+----------+---------------+------------+------------+
| 1 | AAAAAA | AAAAAA | 1 | 1 | 2 |
| 2 | BBBBBB | BBBBBB | 1 | 1 | 2 |
+----------+-----------+----------+---------------+------------+------------+
但就像这里提到的一些人一样,有一个正确的方法来做这些查询。您应该使用JOIN子句:
SELECT *
FROM Person
JOIN Referees
ON (Referees.Referee1ID = Person.PersonId OR Referees.Referee2ID = Person.PersonId)
WHERE Referees.RefereePairID = 1
也许维基百科可以帮助解决一些概念: http://en.wikipedia.org/wiki/Join_(SQL)