宛先ごとに「x」エントリが必要な場合は、MySQL変数ごとに実行できます...
select
di.id_destination,
di.id_image,
i.filepath,
i.size,
@RandSeq := if( @lastDestination = di.id_destination, @RandSeq +1, 1 ) as FinalSeq,
@lastDestination := di.id_destination as carryForward
from
destination_image di
join image i
on di.id_image = i.id_image,
( select @lastDestination := 0,
@RandSeq := 0 ) SQLVars
where
di.id_destination between rangeStart and rangeEnd (or similar criteria for your "range" )
having
FinalSeq = 4 ( just a sample, but your "N" entries per destination desired)
order by
id_destination,
rand()
これにより、宛先ごとに4つ(またはこの場合は「N」)のエントリが取得されます。重要なのはによる順序です。order byは、最初にこの順序でレコードを返し、次に@sql変数を適用します。したがって、宛先ごとに、行は最初にRAND()omizedされますが、単一の宛先内でランダムになります...次の宛先と次の宛先でも同じです...次に@varsは1、2、3を生成します、などの列「FinalSeq」。「HAVING」句は、最終行にその基準を持つエントリを返すことができる行を制限します。したがって、この例では4つだけです。
SQLの明確化。
@variablesは、SQLステートメントで使用されるインライン変数のようなものです... SQLVarsとして(select @someVar:= someValue、@anotherVar:=''、@someDateVar:= getdate())を実行することにより、基本的に作成し、クエリが処理するすべての行に対して設定、変更、および更新できる変数を初期化します... SQLステートメントの最後で、変数が解放されます。一部の人々はそれらを別々のSETコマンドとして事前に宣言し、次にSQL-Selectを実行します。私はそれらをインラインで実行することを好みます。
さて、それらの使用方法... SQL-selectステートメントによって返される行に対してほとんどすべてを追跡するために使用できますが、特定の順序で何かが必要な場合は、order句が最初に処理され、次に@varsで処理されるように記録します...したがって、@varsがプログラム内で設定されることを考えてください。これらはSQLコマンドで処理される順序で設定され、最終結果が何であれ、パディング、トリミング、アッパー、合体などの他の同様の関数呼び出しと同様に、最終列名に格納されます。
さて、何が起こっているのか...手順を見てみましょう...理解のために、1 = A、2 = B、3 = C ---10=に対応する10行の単一のテーブルがあると仮定します。 J。これらは、自動インクリメントなどのレコードの自然な順序です。ここで、rand()によるテーブルの順序からクエリselect *を実行すると、3-C、9-I、2 = B、7=Gなどが得られる可能性があります。最初の4つを返すと、完了です。
ここで、レコード1〜10=AJの同じシナリオをそれぞれ取り上げます。次に、展開して、次のような複数の宛先とサイズの「グループ」を許可します。
ID Ltr Dest Size
1 A X a
2 B Y a
3 C X a
4 D X a
5 E Y b
6 F X c
7 G Y b
8 H X a
9 I Y a
10 J X b
11 K X a
12 L Y a
13 M X a
14 N Y a
今、あなたはすべての目的地のものが欲しいです、しかし例えば単一のサイズ「a」...私はいくつかの余分なものを追加しました。
select * from SampleTable where Size="a" order by rand()
すべての「X」宛先、または「Y(a)」レコードと「X(a)」レコード、または他の同様の利用可能なバランスを取得できます。ただし、サイズ「a」の「X」レコードが3つ、「Y」レコードが3つあるという保証はありません。ORDERをORDERBYDest、rand()に変更すると、すべての「X」エントリが最初に配置され、次に「Y」が制限が機能しなくなります...したがって、私の選択の原則を適用します。宛先とランダムで並べ替え、1つのサイズ= "a"のwhere句を適用すると、次のようになります。
13 M X a
3 C X a
8 H X a
1 A X a
11 K X a
4 D X a
9 I Y a
14 N Y a
2 B Y a
12 L Y a
次に、@variablesをミックスに適用します...@RandSeqと@lastDestinationを適用するだけです
@RandSeq:= if(@lastDestination = di.id_destination、@RandSeq + 1、1)as FinalSeq、@lastDestination:= di.id_destinationasキャリーフォーワード
Start Value of
ID Ltr Dest Size @RandSeq @lastDestination FinalSeq carryForward
13 M X a 0 '' 1 X (current record value of dest)
3 C X a 1 X 2 X
8 H X a 2 X 3 X
1 A X a 3 X 4 X
11 K X a 4 X 5 X
4 D X a 5 X 6 X
9 I Y a 6 X 1 Y (change to Y resets counter to 1)
14 N Y a 1 Y 2 Y
2 B Y a 2 Y 3 Y
12 L Y a 3 Y 4 Y
ここで、「HAVING」句FinalSeq <= 3を適用すると、上記のすべての行がFinalSeq <= 3で取得され、宛先「X」の残りの4、5、6は無視され、「 Y "は無視されます...したがって、指定されたサイズの各宛先から3が残ります。
うまくいけば、これはクエリで何が起こっているのかを明らかにします。