0

クエリが不完全で、サポートが必要です。現在、非効率的な副選択で実行されており、結合を使用すると後で高速になると確信しています。また、クエリに追加する必要のある要素がありますが、その方法がよくわかりません。詳細:

私は3つのテーブルを持っています

- album
 * albumId
 * albumName

- objectTag
 * objectTagObjectId (FK reference to albumId)
 * objectTabTagId (FK reference to tagId)

- tag
 * tagId
 * tagName

私がやろうとしているのは、クエリに渡された別のアルバムにリンクされたタグに基づいて、ランダムなアルバム(たとえば、50)のリストを生成することです。

たとえば、「Britney Spears Greatest Hits」というアルバムがあり、そのアルバムには「pop」と「cheese」のタグが付けられています。次に、クエリにそのブリトニーアルバムのIDを渡し、クエリで「pop」と「cheese」のタグが付けられた50個のランダムな他のアルバムのリストを生成します。

これらのタグが付いたアルバムが20枚しかない場合、クエリはタグに関係なく、他の30枚のレコードにランダムなアルバムを入力する必要があります。

これまでのところ、タグに基づいてランダムなアルバムを取得できます。

SELECT albumId, albumName, objectTagTagId
FROM album
LEFT JOIN objectTag
  ON objectTagObjectId = albumId
WHERE objectTagTagId IN
(
  SELECT objectTagTagId
  FROM album
  LEFT JOIN objectTag
    ON objectTagObjectId = albumId
  WHERE albumId = 2471
)
ORDER BY RAND()
LIMIT 0,50

ただし、前述のように、これは非効率的で不完全です。

a)副選択の代わりに結合を使用してこれをより効率的にするにはどうすればよいですか?それは可能ですか?

b)タグに一致するレコードがx個(たとえば20)しかない場合に、タグに関係なく残りがランダムなレコードで埋められるように、このクエリをどのように変更する必要がありますか?

4

2 に答える 2

1

効率を保証することはできませんが、ここにアイデアがあります...

SELECT * FROM (
  SELECT albumId, albumName, objectTagTagId FROM (
    (
    SELECT count(*) AS cnt, Out.albumId, Out.albumName, objectTagTagId
    FROM album Src
    JOIN objectTag sT
      ON (Src.ablumId = sT.objectTagObjectId)
    JOIN objectTag oT
      USING (objectTabTagId)
    JOIN album Out
    ON (Out.albumId = oT.objectTagObjectId)
    WHERE Src.albumId = 2471
        AND Out.albumId != 2471
    GROUP BY albumId, albumName, objectTagTagId
    )
    UNION     
    (
    SELECT 0 AS cnt, albumId, albumName, null AS objectTagTagId
    FROM album
    ORDER BY RAND()
    LIMIT 50
    )

  ) foo ORDER BY cnt DESC LIMIT 50
) goo ORDER BY RAND()

count(*)/ group byは、アルバムがsrcアルバムと共通するタグの数をカウントします。

ユニオンは、cntがゼロの50枚のフィラーアルバムを提供します。これは、ORDERBYとLIMITによってfooの下部に順序付けられます。

gooのORDERBYRAND()は、順序をランダム化します

于 2012-04-16T06:29:51.267 に答える
0

アルバム2471のすべてのタグが、返却するアルバムに存在する必要があるため、ネストせずに、単純な結合のみを使用して、目的のクエリを作成することはできません。もちろん、INネストをEXISTSネストなどに置き換えることもできます。

于 2012-04-16T06:28:53.690 に答える