次のようなデータベーステーブルがあります。
id version_id field1 field2
1 1 texta text1
1 2 textb text2
2 1 textc text3
2 2 textd text4
2 3 texte text5
うまくいかなかった場合は、行の多くのバージョンが含まれており、テキストデータが含まれています。
クエリを実行して、各IDの最大番号を持つバージョンを返します。 (つまり、上記の2番目と最後の行のみ)。
Version_id DESCで並べ替えながらgroupを使用してみましたが、グループ化後に並べ替えるように見えるため、これは機能しません。
誰でもアイデアはありますか?できないとは信じられない!
更新:
これはうまくいきますが、サブクエリを使用しています:
SELECT *
FROM (SELECT * FROM table ORDER BY version_id DESC) t1
GROUP BY t1.id
列のグループごとの最大値の選択と呼ばれます。 mysqlのいくつかの異なるアプローチがあります。
私がそれをする方法は次のとおりです。
SELECT *
FROM (SELECT id, max(version_id) as version_id FROM table GROUP BY id) t1
INNER JOIN table t2 on t2.id=t1.id and t1.version_id=t2.version_id
これは比較的効率的ですが、mysqlはメモリ内にサブクエリ用の一時テーブルを作成します。このテーブルのインデックス(id、version_id)が既にあると思います。
この種の問題に対して多少なりともサブクエリを使用する必要があるのはSQLの欠陥です( semi-joins も別の例です)。
Mysqlではサブクエリは最適化されていませんが、メモリではなくディスクに書き込まれるほど大きくない限り、非相関サブクエリはそれほど悪くはありません。このクエリのintが2つしかないため、サブクエリはそれが発生するずっと前に数百万行になる可能性がありますが、最初のクエリのselect *サブクエリはこの問題にすぐに悩まされる可能性があります。
これでうまくいくと思いますが、それが最良か最速かはわかりません。
SELECT * FROM table
WHERE (id, version_id) IN
(SELECT id, MAX(version_id) FROM table GROUP BY id)
_SELECT id, version_id, field1, field2
FROM (
SELECT @prev = id AS st, (@prev := id), m.*
FROM (
(SELECT @prev := NULL) p,
(
SELECT *
FROM mytable
ORDER BY
id DESC, version_id DESC
) m
) m2
WHERE NOT IFNULL(st, FALSE);
_
サブクエリはありません。1つあれば、UNIQUE INDEX ON MYTABLE (id, version_id)
をパスします(これが必要だと思います)
このクエリは、次の方法でグループなしでジョブを実行します。
SELECT * FROM table AS t
LEFT JOIN table AS t2
ON t.id=t2.id
AND t.version_id < t2.version_id
WHERE t2.id IS NULL
一時テーブルは必要ありません。
分析機能もいつでも使用できます。これにより、より多くの制御が可能になります
select tmp.* from ( select id,version_id,field1,field2, rank() over(partition by id order by version_id desc ) as rnk from table) tmp where tmp.rnk=1
データのタイプに応じてrank()関数で問題に直面した場合、row_number()またはdense_rank()から選択することもできます。
これは擬似コードですが、このようなものはうまく機能するはずです
select *
from table
inner join
(
select id , max(version_id) maxVersion
from table
) dvtbl ON id = dvtbl.id && versionid = dvtbl.maxVersion
私は通常、サブクエリでこれを行います:
データテーブルからid、version_id、field1、field2を選択します。id=(datatableからidを選択します。id= dt.id version_id desc limit 1の順序で選択します)