我在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方式来实现这一点。

有帮助吗?

解决方案

使用分析函数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子查询以捕获“最新”的更复杂含义。

其他提示

这是“每组最大的N”。问题。它每周在StackOverflow上出现几次。

我通常使用@Steve Kass中的解决方案'回答,但是我没有子查询就这样做了(几年前我习惯了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;

这很难看,但我认为它会起作用

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

我希望有一些方法可以在一个嵌入式选择中获得这两个列,但我不知道。

尝试:

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

第二次尝试。假设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);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top