2016-09-02 30 views
0

所以我有5个独立的select语句。将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> 

更新:

选择*是绝对的要求,这就是为什么用mysql不是一个可行的解决方案。 Mysql无法进行全表连接,而是通过执行表的交叉连接来反映实践。但是,如果你了解交叉连接的缺点,那么当我说某些表将返回数以千计的用户结果时,就会明白,由于交叉连接会为每个条目创建无数个重复行,因此交叉连接不可行,进行交叉连接时,条目会产生数百万和数千万行。 PHP似乎是唯一的解决方案。

我需要一个解决方案,将使用php来结合选择和排序它们的时间不是一个MySQL解决方案。

+0

我仍然希望有一个有效的解决方案,实际上解决了我问的问题。 ,它使用PHP来排序值和回声结果,而不是使用sql来完成。 – Bruce

回答

0

您可以在每个表中定义一个新列以容纳表名。然后,这种查询可以解决你的问题:

SELECT用户名,时间戳,表名从表1工会 选择用户名,时间戳,表名从表2顺序由2递减

+0

我之所以使用fetchAll和*是有原因的,在这种情况下做5个表联合是不实际的,因为如果我这样做,数据最终会返回数百万个结果。我寻求一个php解决方案的原因是因为mysql在执行全表连接时存在缺陷,实际上无法完成全表连接。相反,它会进行交叉连接,最终导致无数个重复的结果。 – Bruce

0

我认为这个问题应该在属于它的地方解决。这显然是一个数据库问题。 但是,如果您有其他问题,则可以先尝试将表中的所有行都提取到数组中。应通过降序时间戳字段选择所有表格。为每个显示相关表中最新项目的表定义一个指针。在循环中查找这些指针指向的行中的最新记录。并在打印出信息后增加这个指针。希望能帮助到你。这里是一个例子:

  $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 if table2 [time] > .....等 – Bruce

+0

嵌套循环效率不高。如果你知道复杂性概念,我的建议会花费你O(maxTableLength),而嵌套循环会花费你O(t1 * t2 * t3 * t4),其中每个t表示相关表的行数。 – msaint

+0

不仅如此,我的方式并没有给我想要的效果,因为if语句将显示一个或另一个没有实际按时间顺序显示。今天会尝试你的方式:) – Bruce