2012-08-02 22 views
9

私は、ID、タイトル、タイムスタンプ、およびcategory_idの列名を持つMySQLデータベース(ブログ)を持っています。最新のタイムスタンプを持つ各カテゴリから1行を選択するにはどうすればよいですか? 3行がカテゴリ1,2,1にある場合、カテゴリの最も高いタイムスタンプが「1」、カテゴリが「2」の行が2番目の列になります。各カテゴリで最大のタイムスタンプを持つ行を選択してください。

私が試み:

SELECT title, timestamp, category_id 
FROM blogs 
WHERE timestamp IN (
    SELECT MAX(timestamp) 
    FROM blogs 
    GROUP BY category_id 
) 
をBUTタイムスタンプが一意ではないので、それは、たとえば、選択されたCATEGORY_ID = 2の行と同じタイムスタンプを有するCATEGORY_ID = 1と余分の行に引くことができ内側のselectステートメントで。

答えて

9

は、MySQLの場合は、このクエリを使用すると、指定した結果セットを返します。

SELECT b.title 
    , MAX(b.timestamp) 
    , b.category_id 
    FROM blogs b 
GROUP BY b.category_id 

、同じ最新の「タイムスタンプ」を持つカテゴリにのみ1つ以上の「タイトル」があることが起こる場合そのカテゴリの行が返されるので、各カテゴリに対して返される「タイトル」は1つだけになります。


注:他のDBMSシステムが原因GROUP BYに表示されていないSELECTリスト内の非集合体の取り扱いのため、上記のようなクエリで例外(エラー)をスローします。

あなたの質問は非常に近いです。すでに各カテゴリの「最新の」タイムスタンプを返す内側のクエリがあります。次のステップは、その最新のタイムスタンプと共にcategory_idを返すことである。

SELECT category_id, MAX(timestamp) AS timestamp 
    FROM blogs 
GROUP BY category_id 

次のステップは、関連する「タイトル」(複数可)を取得するには、blogsにその背中に参加することである

SELECT b.title 
    , b.timestamp 
    , b.category_id 
    FROM (SELECT category_id, MAX(timestamp) AS timestamp 
      FROM blogs 
     GROUP BY category_id 
     ) l 
    JOIN blogs b 
    ON b.category_id = l.category_id AND b.timestamp = l.timestamp 

注:カテゴリに複数の「最新」の行があれば(タイムスタンプの値が一致する)、このクエリは両方を返します。

問題がある場合は、カテゴリに対して2つの行が表示されないように、クエリを変更(または別の方法で記述)することができます。


単にそのクエリにGROUP BY句を追加すると(他のDBMS、MySQLのみではない)動作します

SELECT b.title 
    , b.timestamp 
    , b.category_id 
    FROM (SELECT category_id, MAX(timestamp) AS timestamp 
      FROM blogs 
     GROUP BY category_id 
     ) l 
    JOIN blogs b 
    ON b.category_id = l.category_id AND b.timestamp = l.timestamp 
GROUP BY b.timestamp, b.category_id 

(他のDBMSでは、あなたはMAX(b.title) AS titleb.titleを置き換える、SELECTリストを変更することができあなたがしたい場合。あなたは、行から単一列を返すされているときに動作します。

行は、ORDER BY句を追加し、特定の順序で返される。


+0

最初のエラーが発生しました。あなたの説明は素晴らしいと思いますが、SQLはエラーになります。 「結合」は「元」であると考えられますか? –

+0

@Adam:はい、それはFROMであるはずです。それ以降のクエリは、複数のデータベースで動作するように設計されています。最初はMySQL固有のものです。SELECTリスト内の非集計を処理するため、GROUP BYには表示されません句。 – spencer7593

+0

最初のクエリを見ると、うまくいくようです。しかし、MAX()は最大タイムスタンプ値を持ちますが、行は基本的な順序で返されます。 EX: 最後の3が3である6行がある場合、最初のクエリはID値1,2,3および3であるため、最初の3行の最大タイムスタンプ値を最初の3行のID、タイトルなどで返します。 1と4が同じcat_id 2&5 doと3&6 doを持っていると仮定して最初に戻ることです –

0

あなたもこの方法を試すことができます。 MYSQL 5.6で試してみました。 category_idのタイムスタンプと昇順が最も高い2つのカテゴリを返します。

SELECTタイトル 、タイムスタンプ 、 タイムスタンプによって(CATEGORY_IDによりブロググループからMAX(タイムスタンプ)を選択し)、グループ内のタイムスタンプは、CATEGORY_IDのASC順をCATEGORY_IDブログからCATEGORY_ID。

関連する問題