我在SQLite3数据库中有这个releases
表,列出了每个发布的应用程序版本:
|release_id|release_date|app_id|
|==========|============|======|
| 1001| 2009-01-01 | 1|
| 1003| 2009-01-01 | 1|
| 1004| 2009-02-02 | 2|
| 1005| 2009-01-15 | 1|
因此,对于每个app_id,都会有多行。我有另一张桌子apps
:
|app_id|name |
|======|========|
| 1|Everest |
| 2|Fuji |
我想显示应用程序的名称和最新版本,其中“最新”表示(a)最新的release_date,如果有重复项,(b)最高release_id。
我可以为单个应用程序执行此操作:
SELECT apps.name,releases.release_id,releases.release_date
FROM apps
INNER JOIN releases
ON apps.app_id = releases.app_id
WHERE releases.release_id = 1003
ORDER BY releases.release_date,releases.release_id
LIMIT 1
但当然ORDER BY适用于整个SELECT查询,如果我省略了WHERE子句,它仍然只返回一行。
这是对小型数据库的一次性查询,因此查询速度慢,临时表等都很好 - 我只是无法通过SQL方式来实现这一点。
答案 0 :(得分:1)
使用分析函数ROW_NUMBER()很容易,我猜sqlite3不支持。但是你可以用比以前答案中给出的更灵活的方式来做到这一点:
SELECT
apps.name,
releases.release_id,
releases.release_date
FROM apps INNER JOIN releases
ON apps.app_id = releases.app_id
WHERE NOT EXISTS (
-- // where there doesn't exist a more recent release for the same app
SELECT * FROM releases AS R
WHERE R.app_id = apps.app_id
AND R.release_data > releases.release_data
)
例如,如果您有多个定义“最新”的排序列,则MAX不适合您,但您可以修改EXISTS子查询以捕获“最新”的更复杂含义。
答案 1 :(得分:1)
这是“每组最大的N”问题。它每周在StackOverflow上出现几次。
我通常使用类似@Steve Kass'answer的解决方案,但我没有子查询就这样做了(几年前我习惯了MySQL 4.0,它不支持子查询):
SELECT a.name, r1.release_id, r1.release_date
FROM apps a
INNER JOIN releases r1
LEFT OUTER JOIN releases r2 ON (r1.app_id = r2.app_id
AND (r1.release_date < r2.release_date
OR r1.release_date = r2.release_date AND r1.release_id < r2.release_id))
WHERE r2.release_id IS NULL;
在内部,这可能与NOT EXISTS
语法完全相同。您可以使用EXPLAIN
分析查询以确保。
重新发表您的评论,您可以跳过release_date
的测试,因为release_id
对于确定发布的时间顺序同样有用,我认为它保证是唯一的,所以这简化了查询:
SELECT a.name, r1.release_id, r1.release_date
FROM apps a
INNER JOIN releases r1
LEFT OUTER JOIN releases r2 ON (r1.app_id = r2.app_id
AND r1.release_id < r2.release_id)
WHERE r2.release_id IS NULL;
答案 2 :(得分:0)
这很难看,但我认为它会起作用
select apps.name, (select releases.release_id from releases where releases.app_id=apps.app_id order by releases.release_date, releases.release_id), (select releases.release_date from releases where releases.app_id=apps.app_id order by releases.release_date, releases.release_id) from apps order by apps.app_id
我希望有一些方法可以在一个嵌入式选择中获得这两个列,但我不知道。
答案 3 :(得分:0)
尝试:
SELECT a.name,
t.max_release_id,
t.max_date
FROM APPS a
JOIN (SELECT t.app_id,
MAX(t.release_id) 'max_release_id',
t.max_date
FROM (SELECT r.app_id,
r.release_id,
MAX(r.release_date) 'max_date'
FROM RELEASES r
GROUP BY r.app_id, r.release_id)
GROUP BY t.app_id, t.max_date) t
答案 4 :(得分:0)
第二次尝试。假设ID单调增加且溢出不太可能发生,您可以忽略日期并执行:
SELECT apps.name, releases.release_id, releases.release_date
FROM apps INNER JOIN releases on apps.app_id = releases.app_id
WHERE releases.release_id IN
(SELECT Max(release_id) FROM releases
GROUP BY app_id);