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

複雑なSQLの順序

    「返信ID」は記事の場合は0、コメントの場合は記事番号だと思います。それがあなたのデザインなら、これはうまくいくはずです:

    select * from yourTable
    order by
      case when "reply id" = 0 then id else "reply id" end, id
    

    追加: コメントに追加情報をありがとうございます。最初の順序付けキーはスレッドスターター投稿のcreated_dateであるため、結果を目的の順序に並べるのはそれほど簡単ではありません。これはデータ行にないため、結合が必要です。追加情報に基づく私の最良の推測は次のとおりです(まだ推測を妨げるほど完全ではありません):

    select
      f.id, f.user_id, f.type, f.reply_id, f.text, f.url, f.created_date,
      coalesce(parentfeed.created_date,f.created_date) as thread_date
    from feed as f left outer join feed as parentfeed
    on f.reply_id = parentfeed.id
    order by
      thread_date desc,
      case when f.reply_id = 0 then 0 else 1 end,
      created_date desc, id;
    

    postgreの構文を調整する必要があるかもしれません。これをSQLServerでテストしました。

    それでも希望どおりの結果が得られない場合は、データをどのように戻すかを具体的に説明してください。できれば、ダンプファイル内のデータに対して表示する「id」の順序を教えてください。また その注文の根拠を説明してください。これが私がしたことです:

    1. スレッド内のすべてのメッセージ(スレッド=メッセージとそのコメント)はグループ化する必要があります。

    2. スレッド内で、メッセージを一番上に置き、その後に時系列の逆順にコメントを置きます。最新のcreated/_dateのスレッドが最初で、次に2番目に最新のcreated_dateのスレッドというように続きます。 (サンプルデータには同じcreated_dateのコメントが多数含まれていたため、スレッド内のコメントの2次順序キーとして「id」を使用しました。)

    注: ダンプは、投稿が変更された場合、created_dateがCURRENT_TIMESTAMPに更新されることを示しています。これがライブ掲示板の場合は、コメントの日付がになる可能性があることに注意してください。 親メッセージであり、頻繁に変更される場合(テキストに実際の変更がない場合でも)、スレッドが最上位に留まるという意味です。 (これは私のソリューションには関係ありませんが、注目に値すると思いました。)

    結合が必要なため、このクエリは非常に遅くなります。私の提案:「thread_last_modified」と「item_last_modified」の2つの日付列を維持します。スレッドスターターからコメントに更新をカスケードする必要がありますが、クエリがはるかに単純になる可能性があるため、更新が多くない場合は価値があると思います。デザインにいくつかの変更が必要なため、これはテストしていません。

    select
      id, user_id, type, reply_id, text, url, thread_last_modified, item_last_modified
    from feed
    order by
      thread_last_modified desc,
      case when f.reply_id = 0 then 0 else 1 end,
      item_last_modified desc, id;
    

    追加#2 :ID ::thisOneのコメントを含むスレッドのみが必要な場合は、ON句とORDER BY句の間にこの行を追加できると思います(最初に追加したソリューションでは、結合):

    where parentfeed.id = (
      select coalesce(reply_id,id)
      from feed
      where id = ::thisOne
    )
    

    理論的には、このルックアップはクエリに対して1回だけ評価する必要がありますが、実際には評価しない場合は、::thisOneThreadIDとして事前計算して追加することができます

    where parentfeed.id = ::thisOneThreadID
    

    2番目の解決策については、再度事前計算を行うと仮定して、試してください

    where coalesce(id,reply_id) = ::thisOneThreadID
    

    ちなみに、私のソリューションは両方とも、最後に変更されたスレッドをまったく同時にマージするのではないかと思います...



    1. テーブルに主キーがありません

    2. PostgreSQLクエリのパフォーマンスを理解する

    3. XXXによる並べ替えASCまたはDESCによる並べ替え、動的な順序付け、mysql ..

    4. PowerBIでのMicrosoftAccessの使用