8

私はこれでタオルを投げようとしています。

序文: これを任意の 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 つの注目のアイテムを一番上にフロートさせ、リストの残りの部分を時系列の逆順のリストにするビューがあります。

4

3 に答える 3

1

修正された回答:

select ilv.* from
(select sq.*, @i:=@i+1 rn from
 (select @i := 0) i
  CROSS JOIN 
 (select m.*, o.id o_id, o.timestamp o_t
  from maintable m
  left join othertable o
  on m.id = o.id
  where 1=1
  order by o.timestamp desc) sq
) ilv
order by case when o_t is not null and rn <=3 then rn else 4 end,
         timestamp desc

ここでSQLFiddle 。

必要な複雑な選択条件に一致するようにサブクエリwhere 1=1内の条件を修正し、ページング要件の最終の後にsq適切な基準を追加します。limitorder by

于 2013-07-29T19:25:37.467 に答える
1

以下のようにユニオンクエリを使用できますか?

(SELECT id,timestamp,1 AS isFeatured FROM tbl2 ORDER BY timestamp DESC LIMIT 3)
UNION ALL
(SELECT id,timestamp,2 AS isFeatured FROM tbl1 WHERE NOT id in (SELECT id from tbl2 ORDER BY timestamp DESC LIMIT 3))
ORDER BY isFeatured,timestamp DESC

これはやや冗長かもしれませんが、意味的にはあなたが求めている質問に近いものです。これにより、返される注目の結果の数をパラメーター化することもできます。

于 2016-08-11T20:01:27.577 に答える