1

私は次のdestinationimageおよびdestination_imageテーブルを持っています:

(MYSQL):

  • 宛先:id_destination
  • 画像:id_image、filePath、size
  • destination_image:id_destination、id_image

目的地ごとに、指定されたサイズのランダムなN枚の画像を選択する必要があります。ここで、Nは実行時に定義され、宛先はの範囲から選択されますid_destination

N枚の画像は必要ありません。ランダムなtopN枚の画像だけです。

誰かが私にこれに対する正しいSQLクエリが何であるかについて正しい方向を示すことができますか?

4

2 に答える 2

1

宛先ごとに「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が残ります。

うまくいけば、これはクエリで何が起こっているのかを明らかにします。

于 2012-06-18T14:43:40.530 に答える
1

返される結果の数はORDER BY RAND() LIMIT Nどこにあるかなどを試してください。N例えば:

SELECT i.id_image FROM image i
JOIN destination_image di ON i.id_image = di.id_image
WHERE di.id_destination > N AND di.id_destination < M
AND i.size = X
ORDER BY RAND() LIMIT Y

N、、およびを自分の値Mに置き換えます。XY

于 2012-06-18T13:56:45.843 に答える