【发布时间】:2018-05-08 06:46:02
【问题描述】:
假设,我有以下表格:
项目
- id INT
- 名称 VARCHAR
- owner_id INT
版本
- id INT
- project_id INT
- 标记 VARCHAR
- created_at DATETIME
所有者
- ...(现在无关紧要)
我想检索一组项目,并且我只想加入每个项目的最新版本。 DISTINCT 查询不适用于此目的,因为它限制了从查询返回的列,但我需要所有列。
这是我想出的:
SELECT
projects.id, projects.name, projects.owner_id
FROM
projects
INNER JOIN
(SELECT versions.id, versions.project_id, versions.created_at, versions.tag FROM versions ORDER BY versions.created_at DESC LIMIT 1)
ON
projects.id = versions.project_id
WHERE
projects.owner_id = 1
更一般地说,我想根据特定条件返回有限数量的连接结果。
但我想知道,有没有更好的解决方案?嵌套查询似乎并不优雅,也可能效率不高。我主要是在寻找与 SQLite 兼容的解决方案,但如果其他 SQL 引擎有更好的方法,我也对它感兴趣,因为我过去在使用 MySQL 时已经遇到过这个问题。
更新:我想通过错误的解决方案进一步说明问题。最简单的方法是这样做:
SELECT
projects.id, projects.name, versions.tag, versions.created_at
FROM
projects
INNER JOIN
versions
ON
projects.id = versions.project_id
WHERE
projects.owner_id = 1
ORDER BY
versions.created_at DESC;
这只是一个简单的 JOIN 结构。假设,它会给出以下数据集:
# id name tag created_at
1 1 project1 v2.3 2018-05-08 18:33:42
2 5 project5 v4.0 2018-05-08 11:19:07
3 3 project3 v1.8 2018-05-07 21:41:49
4 5 project5 v3.18 2018-05-07 07:00:26
5 8 project8 v3.12 2018-05-06 08:59:01
6 11 project11 v1.9 2018-05-05 14:27:31
7 5 project5 v3.17 2018-05-04 11:48:22
8 1 project1 v2.2 2018-05-04 05:11:46
9 2 project2 v5.5 2018-05-03 23:08:57
10 7 project7 v6.8 2018-05-03 12:17:33
解决方案是错误的,因为它也返回了不必要的行。我需要从这个数据集中得到第 1、2、3、5、6、9、10 行。 因为它是按versions.created_at字段降序排列的,我需要第一个结果,即每个项目的最新结果。
这就是为什么我需要某种“选择性限制”,它会考虑versions.project_id 字段,就像SELECT DISTINCT 查询一样,但是,我需要从表中返回几乎所有字段,不仅是versions.project_id。
我想知道,这个问题是否有“众所周知”的解决方案,但我不知道?
【问题讨论】:
-
我无法遵循您的逻辑,因为我不知道这些列来自哪些表。
-
@GordonLinoff 我已经为我的示例查询添加了列名。