フィルタリング(開始文字、カテゴリなど)を使用するときにCodeigniter(IMHO)完全に機能し、働いています - 私は2つのクエリを実行していると彼らの間の唯一の違いは、彼らの最後にLIMIT(とOFFSET)があることです。 この2番目のクエリは、行の総数を取得する必要があり、LIMITを持つため、「メイン」クエリで取得できないため、限られた行数を返すため、この2番目のクエリが必要です。Codeigniter + MySql:ページング時に二重クエリを避けるためにCOUNTをこのクエリに統合します。
QUERY 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(この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
モデルコードは(それは厄介だ、私は知っている:)):
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;
}
私が実際に必要とするのは、これらの2つの複雑なクエリを実行する代わりに、より複雑なクエリを取得しても、私はそれから総行数を取得したい。
私はSQL_CALC_FOUND_ROWSについて何かを読んで私はそれを完全に不慣れだと、また多くはそれだけでまれに使用されなければならないので、それがデータベースに追加負担をかけることを言うので、それを実装couldntの。
ご協力いただければ幸いです!
正確には、2番目のステートメント(つまり、 '$ noLimit')を使って何をしようとしていますか?あなたはすべての行を取得しようとしているのですか、すべてのアーティストや曲の合計ですか?あなたがやるべきことに応じて、パフォーマンス上の問題の可能性にかかわらず*保守性*のために2つのクエリとして残す方がよいでしょう。 –
$ noLimitには、最後にLIMITがないときのクエリのレコード数が含まれていることに注意してください。想像してみましょう:あなたはすべてのアーティストや曲を表示したいと思っていますし、ジャンルやファーストレターなどで絞り込んだりしたりしないかもしれません。一度に1ページあたりのレコード数を定義することができます。したがって、私は$ noLimitの行を数え、それを$ total_recordsとしてページ分割に使用し、$ perLimitレコードも$ per_page configを定義する項目としてページ分割スクリプトに送信することにしました – developer10
私に何か提案があればこれは簡単です、私はそれを聞きたいです! – developer10