sql >> データベース >  >> RDS >> Mysql

参加結果に基づいて選択を注文する(最後に送信されたメッセージの会話を並べ替える)

    この問題は、GROUP BYの動作に対するMySQL固有の拡張が原因です。 句。他のデータベースはエラーをスローします...SELECTリストのon-aggregateに似ています」(sql_modeにONLY_FULL_GROUP_BYを含めると、MySQLに同様のエラーをスローさせることができます。)

    messages.createdの問題 これは、GROUPBYの不確定な行の値を参照します。 ORDER BY操作は、GROUP BY操作の後、処理のかなり後の段階で発生します。

    グループごとに作成された「最新」を取得するには、集計を使用します 式MAX(messages.created)

    同じ行から他の値を取得するには、もう少し複雑です。

    createdと仮定します ユニーク 指定されたconversation_id内 グループ(または、一意でないことが保証されておらず、createdに対して同じ値を持つ複数の行を返しても問題ない場合。 ...

    最新のcreatedを取得するには 各conversation_idに対して

    SELECT lm.conversation_id
         , MAX(lm.created) AS created
      FROM conversation lc
      JOIN message lm
        ON lm.conversation_id = lc.id
     WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
     GROUP BY lm.conversation_id
    

    これをインラインビューとして使用して、最新のcreatedを含む行全体を取得できます。

    SELECT c.*
         , m.*
      FROM ( SELECT lm.conversation_id
                  , MAX(lm.created) AS created
               FROM conversation lc
               JOIN message lm
                 ON lm.conversation_id = lc.id
              WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
              GROUP BY lm.conversation_id
           ) l
      JOIN conversation c
        ON c.id = l.conversation_id
      JOIN messages m
        ON m.conversation_id = l.conversation_id
       AND m.created         = l.created
     WHERE (c.creator_id = :userId OR c.to_id = :userId)
    

    注:

    ORDER BYを追加できます 返される行を必要に応じて並べ替える句。

    WHERE 外側のクエリの句は冗長であり、不要である可能性があります。

    SELECT *の使用は避けてください 、および返される式を明示的にリストすることを好みます。




    1. MySQL:どのテーブルが特定のテーブルを参照しているかを確認するにはどうすればよいですか?

    2. HIPAA準拠のデータベースを維持することの重要性

    3. mysqlの列の下部に合計を表示します

    4. OracleのADD_MONTHS()関数