首页 > 解决方案 > 为什么 != 对于 psql 中的这个自连接查询不正确

问题描述

下面是创建表的代码

create table residences(
id integer
references students,
building text
references buildings(name),
room text
);

以下是查询代码。

select a.id, b.id, a.building, a.room
    from residences as a, residences as b
where a.building = b.building
and a.room = b.room
and a.id > b.id
order by a.building, a.room;


|     id |     id | building | room |
+--------+--------+----------+------+
| 881256 | 413001 |   Crosby |   10 |
| 741532 | 496747 |   Crosby |   19 |
| 931027 | 612413 |   Crosby |   31 |
| 958827 | 170267 | Dolliver |    1 |
| 707536 | 104131 | Dolliver |   14 |
| 505241 | 477801 | Dolliver |    8 |
| 824292 | 118199 | Kendrick |   1A |
| 231742 | 105540 | Kendrick |   3B |
+--------+--------+----------+------+

我都试过了

and a.id > b.id

and a.id < b.id

两者都产生了上述相同的结果。

但是,当我使用

and a.id != b.id

它没有用,而是产生了

+--------+--------+----------+------+
|     id |     id | building | room |
+========+========+==========+======+
| 413001 | 881256 |   Crosby |   10 |
| 881256 | 413001 |   Crosby |   10 |
| 496747 | 741532 |   Crosby |   19 |
| 741532 | 496747 |   Crosby |   19 |
| 612413 | 931027 |   Crosby |   31 |
| 931027 | 612413 |   Crosby |   31 |
| 170267 | 958827 | Dolliver |    1 |
| 958827 | 170267 | Dolliver |    1 |
| 104131 | 707536 | Dolliver |   14 |
| 707536 | 104131 | Dolliver |   14 |
| 477801 | 505241 | Dolliver |    8 |
| 505241 | 477801 | Dolliver |    8 |
| 118199 | 824292 | Kendrick |   1A |
| 824292 | 118199 | Kendrick |   1A |
| 105540 | 231742 | Kendrick |   3B |
| 231742 | 105540 | Kendrick |   3B |
+--------+--------+----------+------+

谁能告诉我为什么?

标签: mysqlpsql

解决方案


这是很正常的。您得到的结果与预期的一样,只是前两个结果并不完全相同。如果您注意前两列,您会发现在比较前两个结果时它们被交换了。

但该条件a.id != b.id比其他两个条件限制更少,因此会产生更多结果。

例如:

如果您有值 1、2 和 3 和 required a.id < b.id,那么您将获得尽可能多的组合:

            (1, 2), (1, 3) 和 (2, 3)。

如果你需要a.id > b.id你得到这些组合:

            (2, 1), (3, 1) 和 (3, 2)。

注意这些对与上面的相似,但不一样:每对中值的顺序是相反的——对应于条件。

最后,如果您(仅)需要(限制较少)a.id != b.id,那么您将获得上述所有内容,即除 (1, 1)、(2, 2)、(3, 3) 之外的所有可能对:

          (1, 2), (1, 3), (2, 3), (2, 1), (3, 1) 和 (3, 2)

a.id != b.id然后在您的查询中对它们进行排序,但这并没有改变本质:您获得的结果是其他条件之一的两倍。


推荐阅读