4

これが私の2つのテーブルで、内部結合イベントのIDです。私はこのことをしたい:

表 b には があり10 albumsます4 albums。をeach album選択するone recordと、レコードはアルバム内のランダムな位置になります。

4 つのレコードを取得し(these 4 records with no duplicate id)、これらの 4 つのレコードを内部結合クエリに使用して、titlefromを取得しtable aます。

ここでは、テスト用のほんの少しの記録です。実際、テーブル a に 300,000 レコード、テーブル b に 2,000,000 レコードがあります。

表 a

+-----+-------+
| id  | title | 
+-----+-------+
| 1   | a1    |
+-----+-------+
| 2   | a2    |
+-----+-------+
| 3   | a3    |
+-----+-------+
| 4   | a4    |
+-----+-------+
| 5   | a5    |
+-----+-------+
| 6   | a6    |
+-----+-------+

表 b

+-----+--------+
| id  | album  | 
+-----+--------+
|  1  | album1 | 
+-----+--------+
|  2  | album1 | 
+-----+--------+
|  3  | album1 | 
+-----+--------+
|  6  | album1 | 
+-----+--------+
|  2  | album2 | 
+-----+--------+
|  3  | album2 | 
+-----+--------+
|  5  | album3 | 
+-----+--------+
|  6  | album3 | 
+-----+--------+
|  3  | album4 | 
+-----+--------+
|  2  | album5 | 
+-----+--------+
|  4  | album5 | 
+-----+--------+
|  5  | album5 | 
+-----+--------+
|  1  | album6 | 
+-----+--------+
|  3  | album6 | 
+-----+--------+
|  2  | album7 | 
+-----+--------+
|  4  | album7 | 
+-----+--------+
|  1  | album8 | 
+-----+--------+
|  5  | album8 | 
+-----+--------+
|  3  | album9 | 
+-----+--------+
|  2  | album10| 
+-----+--------+
|  5  | album10| 
+-----+--------+

私はmysqlクエリが苦手です。私の心の中で私はするだろう

select * from b group by album order by random() limit 0,4 

4 枚のアルバムを取得し、内部結合クエリを実行します (このクエリは正しくありません。b.id が重複していないことを確認するにはどうすればよいですか?)

select * from b inner join a on b.id = a.id where (select id from b where b.album = '".$row['album']."'  order by random() limit 1) 

簡単で迅速な方法が必要です。最善の方法は、1 つのクエリを使用することです。どうもありがとう。

4

2 に答える 2

1

AFAIR、「ORDER BY RAND()」は、特にあなたのようなテーブル(200万以上のレコード)では非常に遅いソリューションなので、最初にこれらの種類の記事に似たものを調べることをお勧めします:http://www.greggdev。 com / web / articles.php?id = 6

したがって、クエリを実行する前にテーブル内のレコード数を知ってから、次のようにする必要があります。

"SELECT * FROM `album` LIMIT 1 OFFSET " . rand(0,$count)

これにより、ランダムな1行がもう少し効率的に返されます。

また、アルバム参照を文字列としてトラックテーブルに格納することはお勧めできません。むしろ、albums.idを参照する適切な整数の外部キーalbum_idを使用することをお勧めします。次に、両方のテーブルをより太く結合できます。私があなたなら、私は最初にします:

ALTER TABLE `tracks` add column `album_id` int;
UPDATE `tracks` SET `album_id` = SUBSTRING(`album`,5);

次に、これを実行し、上記のソリューションと組み合わせた後、次のようなものを起動します。

"SELECT * FROM `album` INNER JOIN `tracks`ON `tracks`.`album_id` = `albums`.`id` LIMIT 1 OFFSET " . rand(0,$count)
于 2012-05-06T22:11:41.137 に答える
1

私は MySQL や PHP の専門家ではないので、疑似コードと汎用 SQL を試してみます。albums読みやすくするために、テーブルの名前を に変更しtracksました。

  1. まず、4 つのランダム レコードを PHP アプリケーションに取得します。

    select id from albums order by random() limit 4
    
  2. 次に、4 つの ID の結果セットを繰り返し処理し、対応するトラック (pseudo-php) をフェッチします。

    foreach($album_ids as $id):
        execute_query("select id from tracks where album_id = ? order by random(), limit 1", $id)
    

あなたのトラックを彼らのアルバムにどのようにマッチさせるかは、私には明らかではありません。tracks.album_idへの外部キーのようなものが必要albums.idです。それがクエリの設計方法です。必要に応じて適応する必要があります。私のソリューションの背後にある基本的なロジックは同じままである必要があります。

于 2012-05-06T20:33:12.947 に答える