sql - 三向左连接中的 ORDER BY 与 DISTINCT

标签 sql sqlite

考虑下表。

CREATE TABLE asset (id INT PRIMARY KEY, ...other fields...);
CREATE TABLE property (id INT PRIMARY KEY, name TEXT, value INT);
CREATE TABLE asset_property (asset_id INT, property_id INT);

我希望选择 Assets 并根据属性对其进行排序;但是,我希望将所有 Assets 包括在列表中,而不仅仅是那些具有我正在排序的属性的 Assets 。例如,我可能有
INSERT INTO asset VALUES (1, ...);
INSERT INTO property VALUES (1, 'x', 50);
INSERT INTO property VALUES (2, 'y', 60);
INSERT INTO asset_property VALUES (1, 1);
INSERT INTO asset_property VALUES (1, 2);

INSERT INTO asset VALUES (2, ...);
INSERT INTO property VALUES (3, 'y', 70);
INSERT INTO asset_property VALUES (2, 3);

INSERT INTO asset VALUES (3, ...);
INSERT INTO property VALUES (4, 'x', 80);
INSERT INTO asset_property VALUES (3, 4);

INSERT INTO asset VALUES (4, ...);

我希望选择 Assets 并按“x”属性对其进行排序。这对我来说听起来像是 LEFT JOIN。
SELECT asset.* FROM asset
LEFT JOIN asset_property ON asset.id = asset_property.asset_id
LEFT JOIN property ON asset_property.asset_id = property.id
                      AND property.name = 'x'
ORDER BY property.value;

但是,精明的读者会注意到,这将产生如下结果:
asset.id
1
3
1
2
4

Assets 1 有两行,因为 Assets 1 有一个名为“x”的属性,所以有一行,另一行是因为它有一个未命名为“x”的属性。

这是我的知识/理解不足的地方。为了回避这个问题,我尝试使用 DISTINCT 关键字。
SELECT DISTINCT asset.* FROM asset
LEFT JOIN asset_property ON asset.id = asset_property.asset_id
LEFT JOIN property ON asset_property.asset_id = property.id
                      AND property.name = 'x'
ORDER BY property.value;

这样做的问题是,至少在 SQLite (3.12.1) 下,使用 DISTINCT 关键字似乎覆盖了 ORDER BY 子句:返回的行按asset.id 排序。

虽然我毫不怀疑这种数据库格式似乎是问题的根源,而不是我缺乏 SQL 魔法,但请节省您的精力,而不是建议我更改它;我知道该怎么做。虽然手头的任务可能并不容易,但我希望它是可能的,并且这种格式还有其他优点,使扭曲值得我花时间。谢谢你。

最佳答案

如果您只想要具有 property.name = 'x' 的行,则应使用内部联接 ..

SELECT asset.* FROM asset
LEFT JOIN asset_property ON asset.id = asset_property.asset_id
INNER JOIN property ON asset_property.asset_id = property.id
                  AND property.name = 'x'
ORDER BY property.value;

或与你最后的评论
SELECT asset.* FROM asset
LEFT JOIN asset_property ON asset.id = asset_property.asset_id
INNER JOIN property ON asset_property.property_id = property.id
                  AND property.name = 'x'
ORDER BY case property.value when is null the 1 else 0 end, property.value;

关于sql - 三向左连接中的 ORDER BY 与 DISTINCT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38174457/

相关文章:

mysql如何按用户定义的顺序排序/按字段上的项目数排序

php - 基于数据库条目的不同按钮

sql - 在 mySQL 的 WHERE IN 子句中保持排序

mysql - 在内部选择查询中使用 order by 和 union

sql - 为 SQLite 创建触发器,当插入新记录时,删除旧记录

sql - TransactionScope IsolationLevel 未应用于 Azure

android - 如何在android中显示数据库中的所有行

android - 我在 SQLite (Android) 中收到数据库对象未关闭异常,但我明确关闭了我的数据库...帮助?

android - SQLite 和房间持久性库 : how to combine IN condition and LIKE?

sqlite - 我是否正确定义了所有 key ?我需要添加索引吗?