3

私はmysqlを使用していて、いくつかの問題に直面しています。挿入された最後の行を取得したい。

《以下詳細》

以下は、私がテーブルを作成した方法です。

create table maxID (myID varchar(4))

以下のように4つの値を挿入しました

insert into maxID values ('A001')
insert into maxID values ('A002')
insert into maxID values ('A004')
insert into maxID values ('A003')

を実行するselect myID, last_insert_id() as NewID from maxIDと、以下のような出力が得られます

myId NewID
A001   0  
A002   0  
A004   0  
A003   0    

以下のコードを試したところ、

select myId, last_insert_id() as NewID, @rowid:=@rowid+1 as myrow from maxID, (SELECT @rowid:=0) as init

以下のように出力されます。

myId NewID  rowid
A001   0      1
A002   0      2
A004   0      3
A003   0      4

ただし、コードを使用するselect myId, last_insert_id() as NewID, @rowid:=@rowid+1 as myrow from maxID, (SELECT @rowid:=0) as init where @rowid = 4と、エラーが発生しますUknown column 'myrow' in where clause

を使用するwhere @rowid=4と、テーブルにデータがありません。

データで遊ぶためのリンク

注:ここでは、目的の出力を取得するためだけに 4 を使用しています。後でクエリからこれを取得できます(select max(rowid) from maxID)

最後のレコードのみを表示したい場合、何をする必要があるか教えてくださいA003

御時間ありがとうございます。

アップデート:

テーブルには既に数百万のデータがあるため、以下に示すように新しい列を追加できません。

4

6 に答える 6

5

ほぼ完了しました。掲載順の獲得に成功。そう:

select myId, @rowid:=@rowid+1 as myrow from maxID, (SELECT @rowid:=0) as init ORDER BY myrow desc LIMIT 1;

私のコンソールでは、次のようになります。

mysql> select myId, @rowid:=@rowid+1 as myrow from maxID, (SELECT @rowid:=0) as
init ORDER BY myrow desc LIMIT 1;
+------+-------+
| myId | myrow |
+------+-------+
| A003 |     4 |
+------+-------+
1 row in set (0.00 sec)

デモ

アップデート

ヤクは正しいです。私の解決策は決定論的ではありません。たぶん、少量のレコードで機能します。SELECT ステートメントのデフォルトの並べ替えの信頼性の低さについて、たくさんの投稿を見つけました (ここでは、たとえば)。次のステップ:

  • デフォルトの SELECT ソートが挿入順序と一致するのはどのような条件ですか?
  • 増分IDまたは挿入タイムスタンプなしで、テーブルに最後に挿入されたレコードを取得することは可能ですか?

私はそれが答えではないことを知っていますが、問題を制限する問題を述べています。

于 2012-06-19T15:55:37.730 に答える
2

SELECTaが特定の順序で行を返すことは保証されていないようです(ORDER BYもちろん、句を使用しません)。

SQL-92 標準に従って( p. 373):

< order by 句 > が指定されていない場合、 < カーソル仕様 > で指定されたテーブルは T であり、T 内の行の順序は実装に依存します。

わかりました、MySQL は完全に SQL-92 に準拠しているわけではありませんが、これは重大なヒントです。

Laurynas Biveinis (明らかに Percona と提携している)も次のように述べています

節 (...) がない場合の行の順序はORDER BY、月の満ち欠けによって異なる可能性がありますが、それは問題ありません。

MySQL のマニュアルには、InnoDB について次のように記載されています。

InnoDB は、 [a PRIMARY KEYor NOT NULL UNIQUEindex]が存在する場合、常にそれに従ってテーブル行を並べ替えます。

私に関する限り、MySQLは行の順序を変更しOPTIMIZE TABLEたり、多くの削除や挿入の後に空のスペースを再利用したりすることもできると思います (この例を見つけようとしましたが、これまでのところ失敗しています)。

テーブル構造を考えると、残念ながら、非常に多くの要因によって行の順序が変更された可能性があります。それらが挿入された順序を確実に判断する解決策はありません。もちろん、テーブルを作成してからすべてのバイナリログを保持していない限り;)

sequenceそれでも、テーブルに列を追加したい場合があります。既存の行には不正確なシーケンス番号が割り当てられる可能性がありますが、少なくとも将来の行は正しく順序付けされます。

ALTER TABLE maxID ADD sequence INT DEFAULT NULL;
ALTER TABLE maxID ADD INDEX(sequence);
ALTER TABLE maxID MODIFY sequence INT AUTO_INCREMENT;

http://sqlfiddle.com/#!2/63a8d/1

于 2012-06-21T01:09:25.873 に答える
2

挿入スクリプトからA004、最後に挿入されたレコードではありません。3つ目です。最後のレコードをアルファベット順 (つまりA004) で取得する場合は、次を使用する必要があります。

select myID from maxID order by myID desc limit 1

最後に挿入された行が必要な場合は、自動インクリメント列をテーブルに追加してみませんか? それが、この種のコラムのポイントです。自動インクリメント列は PK である必要はありません (PK である必要がありますが、選択肢がない場合はそうである必要はありません)。

于 2012-01-19T09:07:23.090 に答える
1

MySQLlast_insert_idのヘルプで説明されているように、**自動インクリメント列でのみ使用できます。これは、IDの順序について何かを知らない限り、MySQLに最後に挿入された行を検索させることができないことを意味します。あなたの例が示唆するようにそれらがソートされている場合、あなたは使用することができます

SELECT *
FROM maxID
WHERE myId = max(myId)

ただし、自動インクリメント列をテーブルに追加してから、句で使用すること= last_insert_id()をお勧めします。最後のIDを取得する方法については、このページWHEREも参照してください。

于 2012-01-19T09:02:18.573 に答える
0

last_insert_id は、自動インクリメント フィールドによって生成された最後の値のみを返すため、機能しません。ただし、その解決策は正しい方向に進んでいる可能性があると思います。自動インクリメント整数である別の列を追加することをお勧めします。その後、データを挿入し、挿入した行を取得するには、last_insert_id() を選択します。(任意のプロセスによって挿入された) 最新の行を取得するには、新しい列の最大数を選択するか、desc で並べ替えます。

varchar 列を使用する場合は、アルファベット順の並べ替えを行うことができますが、挿入した最後の行または最後に挿入された行であることは保証されません。

私が考えることができるもう1つの解決策、行を作成してテーブルに挿入し、それを返すストアドプロシージャを作成することです。

@rowid の使用法は、返される行の順序を単純にカウントすることです。古いものから新しいものへの順序で返されるという保証はありません。行が格納される順序に影響を与える可能性のあるさまざまなものがあります。

于 2012-01-19T09:11:52.527 に答える
-1

次のクエリを使用してください。

Select * from maxID order by myId desc limit 1,1;
于 2012-01-19T09:30:58.193 に答える