mysql - 为什么 != 对于 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 |
+--------+--------+----------+------+
谁能告诉我为什么?
解决方案
这是很正常的。您得到的结果与预期的一样,只是前两个结果并不完全相同。如果您注意前两列,您会发现在比较前两个结果时它们被交换了。
但该条件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
然后在您的查询中对它们进行排序,但这并没有改变本质:您获得的结果是其他条件之一的两倍。
推荐阅读
- ios - 删除 tableview 单元格不会更新索引
- c# - Postgres CITEXT 在 DBeaver 中查询时有效,但在 postman 或 swagger 中通过 API 调用时无效
- php - 如何用变量替换子字符串?
- swift - 更改状态模型后需要按两次恢复“自动预览更新已暂停”
- c++ - 有没有办法可以在 C++ 中编辑文件的中间
- r - 在 R 中导入的 data.frame 中将“\\”替换为“\”
- spring-mvc - 如果发布请求包含外部 ID,如何在 Spring 控制器中设置关联记录?
- javascript - 如何将等待功能链接在一起
- node.js - 使用 EJS 时是否需要在 Server.js 文件中使用 { hbs.registerPartials(__dirname + '/views/partials');} 之类的方法?
- asp.net-core - 为什么 Visual Studio 2019 16.9.5 中 .NET Core 3.1 和 .NET 5 的脚手架标识会失败?