5

「Articles」と呼ばれる以下の MySQL テーブルを見てください。

+----+-----------+---------+------------------------+--------------------------+
| id | articleId | version | title                  | content                  |
+----+-----------+---------+------------------------+--------------------------+
|  1 |         1 | 0.0     | ArticleNo.1 title v0.0 | ArticleNo.1 content v0.0 |
|  2 |         1 | 1.0     | ArticleNo.1 title v1.0 | ArticleNo.1 content v1.0 |
|  3 |         1 | 1.5     | ArticleNo.1 title v1.5 | ArticleNo.1 content v1.5 |
|  4 |         1 | 2.0     | ArticleNo.1 title v2.0 | ArticleNo.1 content v2.0 |
|  5 |         2 | 1.0     | ArticleNo.2 title v1.0 | ArticleNo.2 content v1.0 |
|  6 |         2 | 2.0     | ArticleNo.2 title v2.0 | ArticleNo.2 content v2.0 |
+----+-----------+---------+------------------------+--------------------------+

Articles.version が最大数である Articles.id を返すクエリを考え出そうとしています。

実際の Articles テーブルには、10,000 を超えるエントリが含まれています。

したがって、この例では、Articles.id 4 と 6 のみが返されるようにします。私はキーワードdistinctと関数max()を見てきましたが、それを釘付けにすることはできません。

任意の提案をいただければ幸いです...

4

7 に答える 7

5

ここにサブクエリが必要です:

SELECT a.id, a.version
FROM articles a
WHERE a.version = (
    SELECT MAX(version)
    FROM articles b
    WHERE b.articleId = a.articleId
)
于 2009-08-20T11:28:41.993 に答える
4

ここでサブクエリを使用できます。

select
    a.id
from
    articles a
where
    a.version = (select max(version) from articles)

これは相関サブクエリではないため、かなり高速 (結合と同じかそれ以上) であるため、心配する必要はありません。ただし、 max を持つすべての値を返しますarticleid

もちろん、インデックスをスローすることをお勧めします(既にクラスター化されているとarticleid仮定します)。idそれはそれがさらに速く戻るのを助けるでしょう.

コメントに記載されているように、各 の最大バージョンを取得する場合articleidは、次の操作を実行できます。

select
    a.id
from
    articles a
    inner join (select articleid, max(version) 
                from articles group by articleid) as b on
        a.articleid = b.articleid
        and a.version = b.version

これにより、そのサブクエリから結合が作成され、通常、各 の最大値を選択する相関サブクエリよりもはるかに高速になりますarticleid

于 2009-08-20T11:21:30.557 に答える
1

上記のすべての回答は、 DJDonaL3000 が述べた問題を解決する可能性があります。ただし、それらのほとんどは、アプリケーションのパフォーマンスを妨げる相関サブクエリです。クラウド アプリケーションを使用している場合は、上記のクエリを使用しないことをお勧めします。最良の方法は、A と B の 2 つのテーブルを維持することです。A には常に記事の最新バージョンが含まれ、B にはすべてのバージョンの詳細が含まれます。問題は、テーブルへの更新と挿入が増えることですが、テーブル A で通常の選択クエリを実行するだけでよいため、フェッチは高速になります。内部クエリで group by と max を実行するとコストがかかります。

于 2011-12-30T13:54:42.193 に答える
1

SELECT Articles.id FROM Articles WHERE Articles.version IN (SELECT MAX(Articles.version) FROM Articles)

于 2009-08-20T11:22:20.463 に答える
1

たぶん次のようなもの:

select * from articleid in (select max(articleversion) from article)

于 2009-08-20T11:23:10.243 に答える
1

できるよ

SELECT articles.id
  FROM articles a
 WHERE NOT EXISTS(SELECT * FROM articles a2 WHERE a2.version > a.version)

MySQL がそれで動作するかどうかはわかりませんが、Oracle と SQL サーバーはそれで問題ありません。

于 2009-08-20T11:23:36.670 に答える