2016-09-02 3 views
0

私は5つの別々のselectステートメントを持っています。phpで選択ステートメントを結合し、時間でソート

<? 
$stmt=$db->prepare('SELECT * FROM table1 WHERE username = :username'); 
$stmt->bindParam(':user', $username); 
$stmt->execute(); 
$row = $stmt->fetchAll(); 

$stmt=$db->prepare('SELECT * FROM table2 WHERE username = :username'); 
$stmt->bindParam(':user', $username); 
$stmt->execute(); 
$row = $stmt->fetchAll(); 

$stmt=$db->prepare('SELECT * FROM table3 WHERE username = :username'); 
$stmt->bindParam(':user', $username); 
$stmt->execute(); 
$row = $stmt->fetchAll(); 

$stmt=$db->prepare('SELECT * FROM table4 WHERE username = :username'); 
$stmt->bindParam(':user', $username); 
$stmt->execute(); 
$row = $stmt->fetchAll(); 

$stmt=$db->prepare('SELECT * FROM table5 WHERE username = :username'); 
$stmt->bindParam(':user', $username); 
$stmt->execute(); 
$row = $stmt->fetchAll(); 
?> 

私は、すべての結果を組み合わせた最初の最新の時刻と時間に基づいてすべての結果を整理し、その結果から来たテーブルに基づいてメッセージをエコーする必要があります。

各テーブルには行時間があります。

例の結果:

<p>This result was posted 5 minutes ago and came from table 2</p> 
<p>This result was posted 10 minutes ago and came from table 5</p> 
<p>This result was posted 1 day 6 hours ago and came from table 1</p> 
<p>This result was posted 2 weeks ago and came from table 3</p> 
<p>This result was posted 3 weeks ago and came from table 1</p> 

UPDATES:

選択* MySQLを使用して実行可能なソリューションではない理由で絶対条件です。 Mysqlは完全なテーブル結合を行うことができず、代わりにテーブルのクロス結合を実行することで実践を反映します。しかし、クロスジョインの悲惨さを理解すれば、これらのテーブルのいくつかがユーザーのために何千もの結果を返し、クロスジョインはクロスエントリが各エントリに無数の重複した行を作成し、クロス・ジョインを行うと、数百万〜数千万行のエントリが作成されます。 PHPが唯一の解決策であるようです。

phpを使って選択を結合し、時間に基づいてソートするソリューションが必要です。これはmysqlソリューションではありません。

+0

私はまだ私が尋ねた質問を実際に解決する有効な解決策を望んでいます。これはphpを使用して値をソートし、結果をエコーし​​ます.SQLを使用するのではありません。 – Bruce

答えて

0

各テーブルにタブ名を保持するための新しい列を定義することができます。そして、クエリのこの種は、あなたの問題を解決することができます:

SELECTユーザー名、タイムスタンプを、TABLE1組合からtableNameのユーザー名を選択し 、タイムスタンプ、tableNameの表2の順序から2 DESC

+0

私がfetchAllと*を使用していた理由がありました。この場合、5つのテーブル・ユニオンを使用することは実用的ではありません。なぜなら、データが何百万という結果を返すからです。私がPHPソリューションを求めている理由は、mysqlには完全なテーブル結合を行うことに欠陥があり、実際には完全なテーブル結合を行うことができないからです。代わりにクロスジョインが行われ、数十回の重複結果が生じます。 – Bruce

0

ことで、私は問題がすべきだと思いますそれが所属する所で解決される。これは明らかにdbの問題です。 しかし、他の懸念がある場合は、最初にテーブルから配列にすべての行をフェッチすることができます。すべてのテーブルは、降順のタイムスタンプフィールドで順序を選択する必要があります。関連テーブルの最新項目を示すすべてのテーブルのポインタを定義します。あなたのループでは、これらのポインタが指す行の中で最も新しいレコードを見つけます。情報を印刷した後にこのポインタを増やしてください。それが役に立てば幸い。ここに例があります:

  $stmt=$db->prepare('SELECT * FROM table1 WHERE username = :username order by timestamp desc'); 
      $stmt->bindParam(':username', $user); 
      $stmt->execute(); 
      $row[0] = $stmt->fetchAll(); 

      $stmt=$db->prepare('SELECT * FROM table2 WHERE username = :username order by timestamp desc'); 
      $stmt->bindParam(':username', $user); 
      $stmt->execute(); 
      $row[1] = $stmt->fetchAll(); 
      // table lengts 
      $table_len[0]=sizeof($row[0]); 
      $table_len[1]=sizeof($row[1]); 
      //initialize every table pointers to 0 
      $table_pointer[0]=0; 
      $table_pointer[1]=0; 

      while ($table_pointer[0]<$table_len[0] || 
        $table_pointer[1]<$table_len[1]){ 
       // find the newest time 
       $time1=strtotime($row[0][$table_pointer[0]]['timestamp']); 
       $time2=strtotime($row[1][$table_pointer[1]]['timestamp']); 
       $tableWithNewestTime=findNewestTime($table_len,$table_pointer,$time1,$time2); 

       $timeDif=time()-strtotime($row[$tableWithNewestTime][$table_pointer[$tableWithNewestTime]]['timestamp']); 
       echo "This result was posted ".$timeDif." s ego and posted from table".($tableWithNewestTime+1)."<br>"; 
       // increase the table pointer 
       $table_pointer[$tableWithNewestTime]=$table_pointer[$tableWithNewestTime]+1; 
      } 

      function findNewestTime(array $table_len, array $table_pointer, $time1,$time2){ 
        if ($table_pointer[0]>=$table_len[0]) 
         return 1; 
        if ($table_pointer[1]>=$table_len[1]) 
         return 0; 
        if($time1<$time2) 
         return 1; 
        else 
         return 0; 
      } 
+0

私は実際にネストされたforeachループの使用を検討していました。それぞれのクエリを配列として実行し、各配列のループを入れ子にし、if table1 [time]> table2 [time] && table3 [time] && table4 [time] && table5 [time] {else else if table2 [time] > .....など – Bruce

+0

ネストされたループは効率的ではありません。複雑な概念を知っているなら、私のアドバイスはO(maxTableLength)を費やしますが、入れ子にされたループはコストがかかります(t1 * t2 * t3 * t4)。各tは関連するテーブルの行数を表します。 – msaint

+0

それだけでなく、私の方法では、if文がどちらか一方を実際には時間順に表示しないように、私に望ましい効果を与えません。今日あなたに試行されます:) – Bruce

関連する問題