私はこれでタオルを投げようとしています。
序文: これを任意の N で機能させたいのですが、簡単にするために、N を 3 に設定します。
テーブルからデータを取得し、そのテーブルの上位 3 つの値に基づいて並べ替え、その後、他の並べ替え基準にフォールバックする必要があるクエリ (具体的には MySQL) があります。
だから基本的に私はこのようなものを持っています:
SELECT tbl.id
FROM
tbl1 AS maintable
LEFT JOIN
tbl2 AS othertable
ON
maintable.id = othertable.id
ORDER BY
othertable.timestamp DESC,
maintable.timestamp DESC
これはすべて基本的な教科書です。しかし問題は、最初の ORDER BY 句で、othertable.timestamp の 3 つの最大値のみを取得し、maintable.timestamp にフォールバックする必要があることです。
また、maintable に適用される任意の数の WHERE 条件で動作する必要があるため、他のテーブルに LIMIT 3 サブクエリを実行して結合することはできません。
このようなユーザー変数ベースのアプローチでほぼ機能させることができましたが、順序を考慮していないため失敗し、最初に見つかった他の3つのテーブル値を取ります。
ORDER BY
(
IF(othertable.timestamp IS NULL, 0,
IF(
(@rank:=@rank+1) > 3, null, othertable.timestamp
)
)
) DESC
(ステートメントの前に @rank:=0 を付けて)
それで...これに関するヒントはありますか?私はその問題で頭がおかしくなっています。このために私が持っているもう 1 つのパラメーターは、既存の (非常に複雑な) クエリを変更するだけなので、外側のクエリをラップすることはできないということです。また、前述のように、私は MySQL を使用しているため、残念ながら ROW_NUMBER 関数を使用するソリューションは手の届かないところにあります。
事前にすべてに感謝します。
編集。必要なものを説明するために、タイムスタンプをより単純な整数に落としたサンプルデータを次に示します。
maintable
id timestamp
1 100
2 200
3 300
4 400
5 500
6 600
othertable
id timestamp
4 250
5 350
3 550
1 700
=>
1
3
5
6
4
2
何らかの理由で WHERE NOT maintable.id = 5 をクエリに追加すると、次のようになります。
1
3
4
6
2
...現在、4 は、このセットを参照する他のテーブルの上位 3 つの値の中にあるためです。
ご覧のとおり、othertable の ID 4 の行は、タイムスタンプ値の降順で 4 番目であるため、順序付けに含まれていません。したがって、基本的なタイムスタンプで順序付けされるようになります。
これに対する実際の必要性は次のとおりです。「maintable」にコンテンツがあり、「othertable」は基本的に「注目の日付」のタイムスタンプを持つ注目のコンテンツのマーカーです。最後の 3 つの注目のアイテムを一番上にフロートさせ、リストの残りの部分を時系列の逆順のリストにするビューがあります。