2012-05-01 11 views
0

3つのテーブルの情報を含む配列を取得しようとしています。結果は、最初のテーブル、2番目の関連する行、3番目から2番目の関連する行までループする配列です。現時点では、私は3つの別々のSQLクエリーを持っています。そして、それらは1つの単一の配列に改造されます。この結果配列の高速/簡単なクエリ

誰かが、以下の配列を取得するためにこれらのテーブルを照会する最良の方法のアイデアを手伝ってくれるかもしれません。私は現在、各テーブルに1つずつ、3つのクエリを取得しています。 mysql JOINでは簡単なクエリですが、配列に戻すのに問題があります。

私は、少ないクエリで同じ結果を得るためにmysql JOINを使用することを考えていますが、実際にはそれがとても良いかどうかはまったく疑問です。テーブルのおおよそのサイズに数値を追加します。

私はあなたにいくつかの詳細を与えることを許可しなさい:

TABLES

courses(4000 rows) 
course_id----course_date 

groups(50 000 rows) 
group_id----group_size----group_course_id 

users(200 000 rows) 
user_id----user_name----user_group_id 

希望のアレイの例:

[0] => Array('courseinfo' => 
       Array('course_id' => 1234, 
        'course_date' => '2012-08-12') 
      'groups' => 
       Array([0] => Array('group_id' => 345, 
            'group_size' => 3, 
            'group_course_id' => 1234, 
            'users' => Array([0] => Array('user_id' => 456,'user_name' => Pete Cabrinha, 'user_group_id = '345'), 
                [1] => Array('user_id' => 336,'user_name' => John Smith, 'user_group_id = '345')) 
        [1] => Array('group_id' => 345, 
            'group_size' => 3, 
            'group_course_id' => 1234, 
            'users' => Array([0] => Array('user_id' => 456,'user_name' => Pete Cabrinha, 'user_group_id = '1234'), 
                [1] => Array('user_id' => 336,'user_name' => John Smith, 'user_group_id = '1234')))) 

だけの関係に注意してください、それはあまりにも複雑ではありませんホープcourse_idとgroup_course_idの間、およびgroup_idとuser_group_idの間の関係。

私は、現時点で問い合わせる方法の相続人は少し抜粋:

$data = $courses = $read->read_courses(); 
    $i = 0; 
    foreach($courses as $course) 
    { 
     if($data[$i]['groups'] = $read->read_groups($course['course_id'])) 
     { 
      $j = 0; 
      foreach($data[$i]['groups'] as $group) 
      { 
       $data[$i]['groups'][$j]['users'] = $read->read_users($group['group_id']); 
       $j++; 
      } 
     } 
     else {$data[$i]['groups'][0] = array(); $data[$i]['groups'][0]['users'] = array();} 
     $i++; 
    } 

そして最後にインクルードは、私が使用して考え、JOIN ...

 SELECT 
      course.course_id, 
      course.course_date, 

      groups.group_id, 
      groups.group_course_id, 
      groups.group_size, 

      user.user_name 


     FROM course 
     LEFT JOIN groups 
     ON course.course_id = groups.group_course_id 

     LEFT JOIN user 
     ON groups.group_id = user.user_group 

誰かが私をここに役立つことを願って、または正しい方向に私を入れてください - あるいはさらに良いアイデアを思いついてください。

答えて

1

いくつかあり、それを編集答えでわかるようにそのクエリを実行する方法はありますが、データベース全体をPHP配列にロードするべきではありません。あなたのコメントによると、一度に1ヶ月が必要なので、WHERE句を追加して結果をあなたが望む月に制限します。例えば

SELECT ... 
FROM ... 
WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date_col; 

はこれが最後の30日間あなたを与えるだろう。

あるいは、LIMITを使用時のレコードのみ一定数を表示することができる:

LIMIT 0, 100 

はあなたから始まる100件のレコードを与えるオフセット0(最初の100件のレコード)。これにより、ページ付けが容易になります。

あなたが最初、最新のコースを取得したい場合、あなたは、ORDER BYを使用します。

ORDER BY course.course_date DESC 
LIMIT 0, 100 

次に、あなただけ表示するレコードの、そしてもちろんの次のバッチを取得するために、各クエリの制限を変更する必要があり、 100を超えるレコードをダウンロードすることはないため、クエリは非常に高速でほとんどメモリを使用しません。


申し訳ありませんが、あなたはPHPでデータベースの作業をしているようです。

なぜPHP配列の254kエントリを読み込むのですか?あなたは1ページに254kのレコードを表示するつもりはありませんか?パフォーマンスは恐ろしいものになり、ほんの一握りのユーザーがサーバーをクラッシュさせます。

本当に必要なデータとその使用方法を再検討する必要があります。

あなたは何をしようとしていますか?どのようなデータが必要ですか?どのようにデータベースサーバから取得できますか?

+0

実際には、1年間のコースのすべての予約を一度に表示したいだけです。私はいつも額を1ヶ月に制限し、その後facebook-timeline-styleを再クエリします。 – Anonymous

+0

@DanSurfriderその場合は、一度に1か月にクエリを記録するレコードを絶対に制限する必要があります。回答の編集を参照してください。 – Sylverdrag

0

むしろループのために行くそして、この

SELECT * 
    FROM bs_course course 

    LEFT JOIN bs_group AS groups 
    ON course.course_id = groups.group_course_id 

    LEFT JOIN bs_user AS user 
    ON groups.group_id = user.user_group_id 

    ORDER BY course.course_date,course.course_lock,course.course_name,groups.group_status,groups.group_created 

を使用しています。 group_course_idおよびuser_group_idがオン状態で使用されます。

これで結果は得られますが、依然として必要な結果のループを作成する必要があります。

ループが上記の配列を作成するために使用する私の返事を待ちます。

EDIT:配列作成する

この機能を使用:あなたは、他の拡張機能を使用する場合、私はMySQL拡張を使用してメートル

function create_array($resultset){ 
    if(!$resultset){return NULL;} 

    $current_cid=0; 
    $current_cid_counter = 0; 
    $current_gid=0; 
    $current_gid_counter = 0; 
    $current_uid_counter = 0; 
    $return_array = array(); 

    while($row = mysql_fetch_assoc($resultset)){ 
     if($current_cid!=$row['course_id']){ 
      $return_array[$current_cid_counter++]['courseinfo'] = array('course_id'=>$row['course_id'],'course_date'=>$row['course_date']); 
      $current_cid = $row['course_id']; 
      $current_gid_counter = 0; 
      $current_uid_counter = 0; 
     } 
     if($current_gid!=$row['group_id']){ 
      $return_array[$current_cid_counter-1]['groups'][$current_gid_counter++] = array('group_id' => $row['group_id'],'group_size' => $row['group_size'],'group_course_id' => $row['course_id']); 
      $current_gid = $row['group_id']; 
      $current_uid_counter = 0; 
     } 
     $return_array[$current_cid_counter-1]['groups'][$current_gid_counter-1]['users'][$current_uid_counter++] = array('user_id' => $row['user_id'],'user_name' => $row['user_name'], 'user_group_id' => $row['group_id']); 
    } 

    return $return_array; 
} 

を、それに応じて

+0

私の例では、ほんの数のカラムしか持っていませんでしたが、実際にはデータベースにもっと多くのカラムがあります。クエリに複雑なものを追加する必要があるということは非常に不満です。 – Anonymous

+0

あなたはアレイの3レベルの貫通しか必要としません。このコードだけがあなたにそのような配列を与えることができます。 SQLクエリはあなたを助けません。 dbの行数にかかわらず、他の高速な解決策は見つかりません。また、サーバー上では、通常のシステムより処理が速いです。同じページにすべてのデータをフェッチして表示するつもりはないと私に教えてください!!!あなたは、ページネーションやこれの何かを置くのがよいでしょう。一連の選択ボックスがあなたを助けます。 –