MySQL:最新のレコードを取得する


80

次の表で、3つのレコードすべてではなく、サインイン列に基づいての最新のレコードのみを取得するにはどうすればよいid=1ですか?

+----+---------------------+---------+
| id | signin              | signout |
+----+---------------------+---------+
|  1 | 2011-12-12 09:27:24 | NULL    |
|  1 | 2011-12-13 09:27:31 | NULL    |
|  1 | 2011-12-14 09:27:34 | NULL    |
|  2 | 2011-12-14 09:28:21 | NULL    |
+----+---------------------+---------+

回答:


90

MAX(signin)idでグループ化された集計を使用します。これによりsignin、それぞれの最新のものが一覧表示されますid

SELECT 
 id, 
 MAX(signin) AS most_recent_signin
FROM tbl
GROUP BY id

単一のレコード全体を取得するには、IDごとINNER JOINのみを返すサブクエリに対してを実行しますMAX(signin)

SELECT 
  tbl.id,
  signin,
  signout
FROM tbl
  INNER JOIN (
    SELECT id, MAX(signin) AS maxsign FROM tbl GROUP BY id
  ) ms ON tbl.id = ms.id AND signin = maxsign
WHERE tbl.id=1

ここにあなたに基づいて働いていたものだ最初の答え:SELECT id, MAX(signin) FROM tbl GROUP BY id WHERE id=1;
enchance

私は自分の状況で(行全体を取得するために)2番目のソリューションを実装しようとしましたが、常に空の結果セットを取得します
rantsh 2013年

@rantsh xQbertの回答には、私が最初に持っていたものの正しいバージョンが含まれていましたが、私はそれを変更したばかりのソリューションを好みます。
Michael Berkowski 2013年

@MichaelBerkowskiあなたは私の解決策を好むという意味ですか?もしそうなら、私の答えに
賛成票を投じてもかまい

1
@rantshああ、USING明示的なの代わりに経由することを除いて、私が今変更したものに同様のものを追加したことに気づいていませんでしたON。あなたは+1を得ました:)
Michael Berkowski 2013年

83
SELECT *
FROM   tbl
WHERE  id = 1
ORDER  BY signin DESC
LIMIT  1;

明らかなインデックスは、、(id)またはの複数列インデックスになり(id, signin DESC)ます。

この場合、MySQLはNULL値を最後に降順でソートするので便利です。これは、NULL値が存在する可能性がある場合に通常必要なものです。つまり、最新のnull以外の行signinです。

NULL最初に値を取得するには:

ORDER BY signin IS NOT NULL, signin DESC

関連:

SQL標準では、NULL値のデフォルトのソート順は明示的に定義されていません。動作は、RDBMSによってかなり異なります。見る:

ただし、SQL標準で定義され、ほとんどの主要なRDBMSでサポートされている/句がありますが、MySQLではサポートされていません。見る:NULLS FIRSTNULLS LAST


5
これはそれを行う最もクリーンな方法のように感じます!
カランカン2013年

サインイン列のインデックスを作成することを検討してください。これにより、プロセスが大幅に高速化されます
Alexei Tenitski 2014年

最後の行を使用SELECT TOP 1 *して削除しLIMIT 1ます。SQLServerを使用している場合。MySQLまたはPostgresの場合は上記を使用してください。
jaredbaszler 2017

最もクリーン。。。。。。。。
stigzler

シンプルでクリーン!
JeremySwagger19年

9

@xQbertの回答に基づいて、サブクエリを回避し、任意のIDでフィルタリングするのに十分な汎用性を持たせることができます。

SELECT id, signin, signout
FROM dTable
INNER JOIN(
  SELECT id, MAX(signin) AS signin
  FROM dTable
  GROUP BY id
) AS t1 USING(id, signin)

こんにちは、このクエリはどのように機能し、xQbertの回答よりも効率的ですか?両方のクエリがほぼ同時に実行され、クエリの使用部分が通常とオンに置き換わっていることを理解していません。
ZJS 2013

3
Select [insert your fields here]
from tablename 
where signin = (select max(signin) from tablename where ID = 1)


1

私も同様の問題を抱えていました。ページコンテンツの翻訳の最後のバージョンを取得する必要がありました。つまり、バージョン列の番号が最も高い特定のレコードを取得する必要がありました。したがって、バージョン順に並べられたすべてのレコードを選択し、結果から最初の行を取得します(LIMIT句を使用)。

SELECT *
FROM `page_contents_translations`
ORDER BY version DESC
LIMIT 1

1

達成する簡単な方法

私はそれが古い質問であることを知っていますあなたはまた次のようなことをすることができます

SELECT * FROM Table WHERE id=1 ORDER BY signin DESC

上記では、最初のレコードをクエリすると、最新のレコードになります。

1つのレコードに対してのみ、次のようなものを使用できます。

SELECT top(1) * FROM Table WHERE id=1 ORDER BY signin DESC

上記のクエリは、最新のレコードを1つだけ返します。

乾杯!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.