如何从查询中获取第一个和最后一个结果?

时间:2012-06-03 07:29:33

标签: php mysql sql pagination

我正在创建一个分页脚本,我需要在数据库查询中获取第一个和最后一个结果,以便我可以确定当用户单击要转到的页面时显示的结果。这是我现在的代码:

// my database connection is opened

// this gets all of the entries in the database
$q = mysql_query("SELECT * FROM my_table ORDER BY id ASC");
$count = mysql_num_rows($q);
// this is how many results I want to display
$max = 2;
// this determines how many pages there will be
$pages = round($count/$max,0);
// this is where I think my script goes wrong
// I want to get the last result of the first page
// or the first result of the previous page
// so the query can start where the last query left off
// I've tried a few different things to get this script to work
// but I think that I need to get the first or last result of the previous page
// but I don't know how to.
$get = $_GET['p'];
$pn = $_GET['pn'];
$pq = mysql_query("SELECT * FROM my_table ORDER BY id ASC LIMIT $max OFFSET $get");

// my query results appear

if(!$pn) {
    $pn = 1;
}
echo "</table><br />
Page $pn of $pages<br />";
for($p = 1;$p<=$pages;$p++) {
    echo "<a href='javascript:void(0);' onclick='nextPage($max, $p);' title='Page $p'>Page $p</a> ";
}

2 个答案:

答案 0 :(得分:3)

我认为你在那里遇到的问题很少,但我会尝试为你解决这些问题。首先,正如上面的评论所说,您正在使用易受SQL注入攻击的代码。注意这一点 - 您可能希望使用PDO,它与MySQL扩展一样容易使用,并且可以避免许多麻烦(如注入)。

但是对于你的代码,让我们来看看它:

  1. 您应该要求DB计算行数,而不是使用mysql函数,它更有效,所以请使用SELECT count(*) FROM mytable
  2. 对于$pages使用ceil(),因为您希望打印所有行,如果您有$max 5并且有11行,则round将使$pages 2,您真正想要的地方3(最后一页只包含最后第11行)
  3. 在LIMIT中你想要{li> LIMIT row_count OFFSET offset。您可以从页码计算偏移量,因此:$max = row_count$offset = ($max * $page) - $max。在你的代码中$get直接是页面,这意味着你得到$ get'th行(不确定你的JS下一页会发生什么。请记住,并非所有人都使用JavaScript。)

    我在这里准备了一个使用PDO的简单示例,或许可以让您了解使用PDO有多简单。

    选择行显示了如何在SQL中放置参数的示例,在这种情况下它是完全安全的,'SELECT * FROM pseudorows LIMIT '.$start.','.$max我想做一个例子它是多么容易(然后是安全的):

    // DB config
    $DB_NAME    = 'test';
    $DB_USER    = 'test';
    $DB_PASSWD  = 'test';
    
        // make connection
    try {
        $DB_CONN = new PDO("mysql:host=localhost;dbname=".$DB_NAME, $DB_USER, $DB_PASSWD);
        $DB_CONN->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch (PDOException $e) {
        die($e);
    }
    
    // lets say user param 'p' is page, we cast it int, just to be safe
    $page   = (int) (isset($_GET['p'])?$_GET['p']:1);
    // max rows in page
    $max    = 20;
    
    // first select count of all rows in the table
    $stmt = $DB_CONN->prepare('SELECT count(*) FROM pseudorows');
    $stmt->execute();
    if($value = $stmt->fetch()) {
        // now we know how many pages we must print in pagination
        // it's $value/$max = pages
        $pages = ceil($value[0]/$max);
    
        // now let's print this page results, we are on $page page
        // we start from position max_rows_in_page * page_we_are_in - max_rows_in_page
        // (as first page is 1 not 0, and rows in DB start from 0 when LIMITing)
        $start = ($page * $max) - $max;
        $stmt = $DB_CONN->prepare('SELECT * FROM pseudorows LIMIT :start,:max');
        $stmt->bindParam(':start',$start,PDO::PARAM_INT);
        $stmt->bindParam(':max',  $max,PDO::PARAM_INT);
        $stmt->execute();
    
        // simply just print rows
        echo '<table>';
        while($row = $stmt->fetch()) {
            echo '<tr><td>#'.$row['id'].'</td><td>'.$row['title'].'</td></tr>';
        }
        echo '</table>';
    
        // let's show pagination
        for($i=1;$i<=$pages;$i++) {
            echo '[ <a href="?p='.$i.'">'.$i.'</a> ]';
        }
    }
    

答案 1 :(得分:0)

mysql_fetch_array返回一个关联数组

这意味着您可以使用resetend获取第一个和最后一个结果:

$pqa = mysql_fetch_array($pq);
$first = reset($pqa);
$last = end($pqa);

我不知道你打算如何使用实际结果,只是页码应足以分页。

仍然,希望它有所帮助。 是的,升级到mysqli,所以你的代码不会过时。