1

基本的に 3 つの選択が 2 つの UNION と一緒に接着されています。すべての選択列は、各選択内で同じです。それらのすべてで異なるのは、WHERE句です。それらはすべてほぼ同じ where 条件を持っています (他と異なる条件はそれぞれに 1 つだけあります)。私の発言は次のようになります

(SELECT column_name1, column_name2, column_name3, ....
FROM users
LEFT JOIN ...
    ON ...
LEFT JOIN ...
(bunch of LEFT JOINS)
.
.
.
WHERE (SAME CONDITIONS) AND program_id = 3 order by RAND() limit 100)
UNION
(SELECT column_name1, column_name2, column_name3, ....
FROM users
LEFT JOIN ...
    ON ...
LEFT JOIN ...
(bunch of LEFT JOINS)
.
.
.
WHERE (SAME CONDITIONS) AND program_id = 2 order by RAND() limit 100)
(SELECT column_name1, column_name2, column_name3, ....
FROM users
LEFT JOIN ...
    ON ...
LEFT JOIN ...
(bunch of LEFT JOINS)
.
.
.
WHERE (SAME CONDITIONS) AND program_id = 1 order by RAND() limit 100)

そして、この選択から、他のデータも選択したいと思います。ユーザーの順序を変えたいのですが、ユーザーの順序は常に最高のプログラムから最低のプログラムにする必要があるため、このようにします。問題は、どうにかしてこの選択を短くすることはできますか? ほとんどすべてが同じで、条件が 1 つしかないというのは意味がないからです。そこにバグを見つけたり、何かを変更したい場合 (これは選択の一部にすぎないため)、すべてを書き直さなければなりません。手伝ってくれませんか ?

4

1 に答える 1

1

以下を試すことができます。最初に program_id で、次にランダムで行を並べ替えます。ユーザー定義の変数を使用して行をランク付けし、新しい program_id に到達するたびに 1 から始めます。最後に、ランクが 100 以下の行のみを返します。

SELECT
  id,
  program_id


FROM(
  SELECT
    id,
    program_id,
    @rank := IF(@program = program_id, @rank + 1, 1) AS rank,
    @program := program_id


  FROM(
    SELECT
      id,
      program_id

    FROM users

    WHERE program_id IN(1, 2, 3)
      #AND [other conditions]

    ORDER BY
      program_id,
      RAND()
  ) AS Derived

  JOIN (SELECT @program := 0, @rank := 0) AS var
) AS Derived


WHERE rank <= 100

ORDER BY
  program_id,
  id DESC

http://sqlfiddle.com/#!2/92d7b/1

于 2013-08-04T22:15:31.363 に答える