PHP / MySQL - 使用各种ORDER BY子句进行分页

时间:2011-08-15 23:16:34

标签: php mysql pagination sql-order-by

我有以下查询:第一个作为分页计数,第二个用数据填充结果表。它们都运行得很好,但我也希望在表格中添加Ordering功能,并且已经朝着这个方向做了一些努力。

基本上,我已将MySQL查询分解为存储在变量中的部分,这些部分可能会也可能不会根据用户的意愿进行分配,如表单的提交和GETting所表示的那样。我只处于初级阶段,这对我来说是合乎逻辑的。这可能不是正确的方法!

数据在数据库中输入时默认排序。该表一次填充15行。理想情况下,用户可以选择以另一种方式订购动物的数据 - 例如,按年龄或颜色。选择是通过向页面本身提交表单,重新提交查询,结果再次以15行页面输出。

到目前为止,这是我的代码:

分页:

$genderid = $_GET['groupid'];
$sortby = $_GET['sortby'];

##################

if (isset($_GET['pageno'])) { $pageno = $_GET['pageno']; }
    else { $pageno = 1; }

    $initialcount = "SELECT count(*) 
                FROM profiles
                WHERE ProfileName != 'Unknown'";

        if ($genderid > 0) {
            $genderquery = " AND ProfileGenderID = $genderid";
            }                 
        if ($sortby == 'age') {
            $orderby = " ORDER BY ProfileYearOfBirth ASC";
            } 
        elseif ($sortby == 'colour') {
            $orderby = " ORDER BY ProfileAdultColourID ASC";
            }

    $finalcount = ($initialcount . ' ' . $genderquery . ' ' . $orderby);

    $result = mysql_query($finalcount) or trigger_error();
    $query_data = mysql_fetch_row($result);
    $numrows = $query_data[0];

    $rows_per_page = 15;
    $lastpage = ceil($numrows/$rows_per_page);

    $pageno = (int)$pageno;
    if ($pageno > $lastpage) {
        $pageno = $lastpage;
    }
    if ($pageno < 1) {
        $pageno = 1;
    }

    $limit = 'LIMIT ' .($pageno - 1) * $rows_per_page .',' .$rows_per_page;


    if ($pageno == 1) 
        {
            echo '<p class="pagination">';
            echo '<span class="first"><< First</span><span class="previous">< Previous</span>';
        } 
    else    
        {
            echo '<p class="pagination">';
            echo "<span class='first'><a href='{$_SERVER['PHP_SELF']}?pageno=1'><< First</a></span>";
            $prevpage = $pageno-1;
            echo "<span id='class'><a href='{$_SERVER['PHP_SELF']}?pageno=$prevpage'>< Previous</a></span>";
        }

    echo '<span class="pagination-nav">' . "Page $pageno of $lastpage" . '</span>';

    if ($pageno == $lastpage) 
        {
            echo '<span class="next">Next ></span><span class="last">Last >></span>';
            echo '</p>';
        } 
    else 
        {
            $nextpage = $pageno+1;
            echo "<span class='next'><a href='{$_SERVER['PHP_SELF']}?pageno=$nextpage'>Next ></a></span>";
            echo "<span class='last'><a href='{$_SERVER['PHP_SELF']}?pageno=$lastpage'>Last >></a></span>";
            echo '</p>';
        } 

输出:

     <table class="admin-display">
    <thead>
        <tr>
            <th>Name:</th>
            <th>Age:
                <form class="sorting-form" method="GET" action="">
                <input type="hidden" name="sortby" value="age" />
                <input type="hidden" name="groupid" value="<?php echo $genderid; ?>" />
                <input type="submit" value="&#8657;" class="sort-submit" />
                </form>
            </th>
            <th>Colour:
                <form class="sorting-form" method="GET" action="">
                <input type="hidden" name="sortby" value="colour" />
                <input type="hidden" name="groupid" value="<?php echo $genderid; ?>" />
                <input type="submit" value="&#8657;" class="sort-submit" />
                </form>
            </th>
            <th>Gender:</th>
            <th>Owner:</th>
            <th>Breeder:</th>
        </tr>
    </thead>    

<?php

    $initialquery = "SELECT ProfileID, ProfileOwnerID, ProfileBreederID, 
            ProfileGenderID, ProfileAdultColourID, ProfileColourModifierID, ProfileYearOfBirth, 
            ProfileYearOfDeath, ProfileLocalRegNumber, ProfileName,
            owner.ContactFirstName AS owner_fname, owner.ContactLastName AS owner_lname,
            breeder.ContactFirstName AS breeder_fname, breeder.ContactLastName AS breeder_lname,
            BreedGender, BreedColour, BreedColourModifier
            FROM profiles
                        LEFT JOIN contacts AS owner
                            ON ProfileOwnerID = owner.ContactID
                        LEFT JOIN contacts AS breeder
                            ON ProfileBreederID = breeder.ContactID
                LEFT JOIN prm_breedgender
                            ON ProfileGenderID = prm_breedgender.BreedGenderID
                        LEFT JOIN prm_breedcolour
                            ON ProfileAdultColourID = prm_breedcolour.BreedColourID
                        LEFT JOIN prm_breedcolourmodifier
                            ON ProfileColourModifierID = prm_breedcolourmodifier.BreedColourModifierID
                      WHERE ProfileName != 'Unknown'";

$finalquery = ($initialquery . ' ' . $genderquery . ' ' . $orderby . ' ' . $limit);

$result = mysql_query($finalquery) or trigger_error("SQL", E_USER_ERROR);
//process results

数据仍然正确输出(最初),用户也可以成功重新提交查询。问题出现时 - 在通过除默认之外的任何其他订购之后 - 我点击前进页面。页面更改后,排序将恢复为默认值。我不知道如何在初始重新提交之后维护ORDER BY子句。

在我开始破解代码之前,这是我所得到的,事情开始变得毛茸茸。我需要有人指出明显的错误!非常感谢提前:))

3 个答案:

答案 0 :(得分:1)

这听起来应该在AJAX调用中处理。从理论上讲,你可以在整个会话期间保持初始和递增状态(使用会话变量,隐藏的表单字段,甚至cookie),但我认为你会更乐意一次异步地抓取X记录并保持参数客户端,直到你想要下一页。

根据海报的查询,在会话中存储必要的值看起来像这样:

session_start();

$startat = intval($_REQUEST["startat"]);
$numrows= intval($_REQUEST["numrows"]);

if (isset($_SESSION['base_query'])){
    $query = $_SESSION['base_query'];
} else {
    $query = <query construction minus limit clause>;
    $_SESSION['base_query'] = $query;
}


$query .= " LIMIT $startat, $numrows";

<query db/ send results>

这会给你这个想法吗?

答案 1 :(得分:0)

也许你可以使用http://www.datatables.net/解决这个问题?它是一个客户端ajax解决方案,为您订购结果。而且每次都避免重新加载整个页面。

答案 2 :(得分:0)

好的,我在接下来的几个小时里完成了我的工作,并想出了一个解决方案。它不使用AJAX或SESSIONS,并且无疑是可怕的,但它适合我现在的技能水平。

首先,我更改了分页脚本,为offset参数提供了一个不同的值:

$title = intval($_GET['groupid']);
$genderid = intval($_GET['groupid']);
$sortby = $_GET['sortby'];

##################################

    $initialcount = "SELECT count(*) FROM profiles WHERE ProfileName != 'Unknown'";

    if($genderid > 0) {
        $where = "AND ProfileGenderID = $genderid";
        $finalcount = ($initialcount . ' ' . $where);
        }
    else { $finalcount = $initialcount;  }

    $result = mysql_query($finalcount) or trigger_error("SQL", E_USER_ERROR);
    $r = mysql_fetch_row($result);
    $numrows = $r[0];

$rowsperpage = 15;
$totalpages = ceil($numrows / $rowsperpage);

if (isset($_GET['currentpage']) && is_numeric($_GET['currentpage'])) {
   $currentpage = (int) $_GET['currentpage'];
} 
    else { $currentpage = 1; }

if ($currentpage > $totalpages) {
   $currentpage = $totalpages;
} 

    if ($currentpage < 1) 
       {  $currentpage = 1; } 

$offset = ($currentpage - 1) * $rowsperpage;

我还将分页链接更改为a)保存当前性别(整体)排序的值,以及后续排序(年龄,颜色);和b)显示编号的页面链接,即谷歌:

// range of num links to show
$range = 3;

##############

        $range = 3;

        echo '<p class="pagination">';
        if ($currentpage == 1) 
        {
            echo '<span class="first"><< First</span><span class="previous">< Previous</span>';
        } 
        if ($currentpage > 1) {
            echo "<span class='first'><a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid&currentpage=1'><< First</a></span>";
            $prevpage = $currentpage - 1;
            echo "<span class='previous'><a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid&currentpage=$prevpage'>< Previous</a></span>";
        }

        echo '<span class="pagination-nav">';

        for ($x = ($currentpage - $range); $x < (($currentpage + $range) + 1); $x++) {
            if (($x > 0) && ($x <= $totalpages)) {
                    if ($x == $currentpage) {
                        echo " [<b>$x</b>] ";
                    } 
                    else {
                        echo " <a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid&currentpage=$x'>$x</a> ";
                    }
            }
        }

        echo '</span>';

        if ($currentpage != $totalpages) {
               $nextpage = $currentpage + 1;
               echo "<span class='next'><a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid&currentpage=$nextpage'>Next ></a></span>";
               echo "<span class='last'><a href='{$_SERVER['PHP_SELF']}?sortby=$sortby&groupid=$genderid&currentpage=$totalpages'>Last >></a></span>";
        }
        if ($currentpage == $totalpages) 
            {
                echo '<span class="next">Next ></span><span class="last">Last >></span>';
            } 

        echo '</p>';

最后构建了查询:

$baseQuery = "SELECT ProfileID, ProfileOwnerID, ProfileBreederID, 
                ProfileGenderID, ProfileAdultColourID, ProfileColourModifierID, ProfileYearOfBirth, 
                ProfileYearOfDeath, ProfileLocalRegNumber, ProfileName,
                owner.ContactFirstName AS owner_fname, owner.ContactLastName AS owner_lname,
                breeder.ContactFirstName AS breeder_fname, breeder.ContactLastName AS breeder_lname,
                BreedGender, BreedColour, BreedColourModifier
                FROM profiles
                            LEFT JOIN contacts AS owner
                                ON ProfileOwnerID = owner.ContactID
                            LEFT JOIN contacts AS breeder
                                ON ProfileBreederID = breeder.ContactID
                    LEFT JOIN prm_breedgender
                                ON ProfileGenderID = prm_breedgender.BreedGenderID
                            LEFT JOIN prm_breedcolour
                                ON ProfileAdultColourID = prm_breedcolour.BreedColourID
                            LEFT JOIN prm_breedcolourmodifier
                                ON ProfileColourModifierID = prm_breedcolourmodifier.BreedColourModifierID
                          WHERE ProfileName != 'Unknown'";


    if($sortby == 'age') {
        $orderby = "ORDER BY ProfileYearOfBirth ASC";
        }
    elseif ($sortby == 'colour') {
        $orderby = "ORDER BY ProfileAdultColourID ASC";
        }

    $limitClause = "LIMIT $offset, $rowsperpage";

    $finalQuery = ($baseQuery . ' ' . $where . ' ' . $orderby . ' ' . $limitClause);

$result = mysql_query($finalQuery) or trigger_error("SQL", E_USER_ERROR);

有效作为击中芝士蛋糕的锤子:) 非常感谢上面的贡献者,特别是向我介绍INTVAL(以及进展,铸造)。