mysql - 代码点火器+MySql : Integrate COUNT into this query to avoid double queries when paginating

标签 mysql sql pagination sql-calc-found-rows

由于 Codeigniter(恕我直言)中的分页缺少一些好东西,以便在使用过滤器(开始字母、类别等)时更容易实现,即使我的分页功能齐全且有效 - 我有两个查询正在运行,唯一的区别是它们是其中之一在末尾具有 LIMIT(和 OFFSET)。 需要第二个查询,因为我必须获取总行数,而对于我的“主要”查询,我无法获取它,因为它有 LIMIT,所以它返回有限的行数。

查询 1(“主要”查询)

SELECT art.*, songs.numsongs 
        FROM _tbl_artists AS art
        LEFT JOIN 
        (SELECT _ARTIST_ID, COUNT(*) AS numsongs 
        FROM _tbl_songs GROUP BY _ARTIST_ID) AS songs 
        ON art._ID_ORIGINAL = songs._ARTIST_ID 
        WHERE art._artist_type = 0 AND art._ARTIST_NAME LIKE 'C%' AND art.id > 0 ORDER BY art._ARTIST_NAME ASC LIMIT 20, 20

QUERY 2(这个算行)

SELECT art.*, songs.numsongs 
        FROM _tbl_artists AS art
        LEFT JOIN 
        (SELECT _ARTIST_ID, COUNT(*) AS numsongs 
        FROM _tbl_songs GROUP BY _ARTIST_ID) AS songs 
        ON art._ID_ORIGINAL = songs._ARTIST_ID 
        WHERE art._artist_type = 0 AND art._ARTIST_NAME LIKE 'C%' AND art.id > 0 ORDER BY art._ARTIST_NAME ASC

模型代码(很乱,我知道 :)):

function loadArtists($type='', $letter='', $uriOffset=0, $perPage='')
{
    $letterEval = preg_match('[0-9]', $letter);
    switch($letterEval):
        case 1:
            $operator = 'REGEXP';
            $letter = "^[0-9]";
            $s = '';
            break;
        case 0:
            $operator = 'LIKE';
            $letter = "$letter";
            $s = '%';
            break;
        default: 0; break;
    endswitch;

    $query = "SELECT SQL_CALC_FOUND_ROWS art.*, songs.numsongs 
        FROM _tbl_artists AS art
        LEFT JOIN 
        (SELECT _ARTIST_ID, COUNT(*) AS numsongs 
        FROM _tbl_songs GROUP BY _ARTIST_ID) AS songs 
        ON art._ID_ORIGINAL = songs._ARTIST_ID 
        WHERE";
        if($type == 0 || $type == 1)
            $query .= " art._artist_type = $type AND";

        if($letter != '')
            $query .= " art._ARTIST_NAME $operator '$letter$s' AND";
        else
            $query .= '';

    $query .= " art.id > 0 ORDER BY art._ARTIST_NAME ASC";

    if ($uriOffset != '')
        $limited = $query . " LIMIT $uriOffset, $perPage";
    else
        $limited = $query . " LIMIT $perPage";

    $noLimit = $this->db->query($query);
    $withLimit = $this->db->query($limited);

    $numRows = $withLimit->num_rows(); 

    $resultStack = array();
    $resultStack = array($numRows);


    if($withLimit->num_rows() > 0)
    {
        $result = $withLimit->result();
        $message = '';
    }

    else
    {
        $result = NULL;
        $message = 'Nema rezultata';
    }

    array_push($resultStack, $result, $message);

    return $resultStack; //$resultStack;
}

所以我真正需要的是,与其运行这两个复杂的查询,我宁愿进行一个查询,即使它变得更复杂,但我想从中获取总行数。

我阅读了一些有关 sql_calc_found_rows 的内容,但无法实现它,因为我完全不熟悉它,而且很多人说它会给数据库带来额外的压力,因此它应该只在极少数情况下使用。

任何帮助将不胜感激!

最佳答案

你可以这样做来获取(未分页的)行的总数:

( See the output on SQL Fiddle )

SELECT art.*, songs.numsongs, artist_count.total
    FROM _tbl_artists AS art
    JOIN (
        SELECT COUNT(*) as total
        FROM _tbl_artists as art
        WHERE art._artist_type = 0
        AND art._ARTIST_NAME LIKE 'C%' AND art.id > 0
    ) artist_count
    LEFT JOIN (
        SELECT _ARTIST_ID, COUNT(*) AS numsongs 
        FROM _tbl_songs GROUP BY _ARTIST_ID
    ) AS songs ON art._ID_ORIGINAL = songs._ARTIST_ID 
    WHERE art._artist_type = 0
    AND art._ARTIST_NAME LIKE 'C%' AND art.id > 0
    ORDER BY art._ARTIST_NAME ASC
    LIMIT 20, 20;

第一个子查询仅使用您提供的搜索艺术家的条件并计算满足这些条件的总行数(艺术家)。我们不需要在这里 JOIN_tbl_songs 表,因为我们不关心这些艺术家是否在此子查询中有任何歌曲。

关于mysql - 代码点火器+MySql : Integrate COUNT into this query to avoid double queries when paginating,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6698537/

相关文章:

php - 清理表单提交上的变量

mysql - Rails with mysql "Unknown type ' json' for column 'special_info' "

mysql - 如何更改mysql中特定字段的所有记录

java - 通过传递表名和列名从 Oracle 表中删除行

sql - 在 MySQL 中创建外键产生错误 :

MySQL 查询 : Values from multiple cells in a single cell

sql - 甲骨文解码与 NVL

php - 分页和 url 编码帮助

mysql - 自定义 Laravel 分页计数查询

ruby-on-rails - 没有 gem 的分页 Next, Previous, Name.order( :id). limit(10).offset(0) 的按钮