MySQLのLimit句でページ分割する方法と一括処理の方法

このQ&Aのポイント
  • MySQLのLimit句を使用して、PHP+MySQLでページ分割を実現する方法について解説します。
  • ページ分割により検索結果を10件ずつ表示し、ページ番号をGETパラメータで渡して動的に変更することができます。
  • また、一括処理(削除など)を実現するために、チェックボックスを使用し、選択されたレコードの情報をGETパラメータで渡す方法も紹介します。
回答を見る
  • ベストアンサー

MySQLのLimit句によるページ分割について

MySQL初級です。 PHP+MySQLで、検索ページを作成しています。 SELECT部を簡略して書くと・・ (ページ番号$get_pageNoをGETで渡して、10件ずつ検索結果を表示したい。) $sql = "SELECT Id FROM houjin WHERE (word LIKE '%${ワード}%')"; $sqlLimit .= "ORDER BY Id ASC limit " . ($get_pageNo*10) . ", 10"; 表示まではできていて、前へ、次へ、のリンクで、10件ずつ抽出できるところまでは、 できました。 さらに、抽出されたレコードに、チェックボックスをつけて、 ユーザーに選択させて、処理(削除など)を行いたいわけです。 表示されたあるレコードにチェックをつけて、 次のページのレコードにもチェックをつけて、 一括処理(削除など)ができる方法を探しています。 ページ番号をGETで渡してリロードさせているので、 チェックされたレコード番号もGETで渡す、しか方法はないでしょうか? Limitにこだわってはいません。 よい方法、アイデアがあれば教えてください。

  • PHP
  • 回答数2
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.2

現在ページのcheckbox の状態を送信するには、postであれ、getであれ、リンクではなく、<form>からのsubmitが必要です。でなければ、ajax送信になります。 <form>には複数のsubmitボタンをおけます。クリックしたsubmitボタンのname:valueだけ送信されてくるので、name で区別して、次ページか前ページかを切り分け可能です。 そして、これまでにcheckが付いたid をhidden でいれておけば、以前のデータを持ち回ることが出来るし、前ページへ戻ったときに、表示範囲のidなら、先にcheckを入れておいて、はずれてたら、持ち回り中止扱いと言うことも出来ます。 あまり細かく検討はしてないけど、判定手順として以下のようなソース。 <?php if(isset($_POST["del"])){ // 削除用を呼び出す $_POST["c"] の配列に削除対象データ exit; } if( isset($_POST["p"]) ){ /* 前回ページ番号を hidden にいれておいて、prev と nextのどちらが送信されてきたかで、今回ページ番号算出 */ $p = intval($_POST["p"]) + ( isset($_POST["next"])?1:(isset($_POST["prev"])?-1:0) ); }else{ $p=1; } // databaseから取り出し  コード省略 , $max に最大ページ数も取得しておく $lines = $db->fetchAll(); ?> <form action="" method="post" > <table> <?php foreach($lines as $k=> $line): $num = $k+($p-1)*10; ?> <tr><td><input type="checkbox" name="c[<?=$num ?>]" value="<?=$line['id'] ?>" <?php echo (isset($_POST["c"][$num]))?"checked":""; ?> > <?=$num ?></td><td><?=$line['data'] ?></td></tr> <?php endforeach; ?> </table> <?php foreach($_POST[c] as $k=>$val): ?> $n = intval($k); if( $n< ($p-1)*10 or $n>= $p*10 ){ <input type=hidden" name="c[<?=$k ?>]" value="<?=$val ?>"> } <?php endforeach; ?> <input type=hidden" name="p" value="<?=$p ?>"> <?php if($p>1): ?> <submit name="prev" value="前ページ <?=$p-1 ?>"> <?php endif; ?> <?php if($p<$max): ?> <submit name="next" value="次ページ <?=$p+1 ?>"> <?php endif; ?> <submit name="del" value="削除実行"> </form>

その他の回答 (1)

  • hwoa1024
  • ベストアンサー率36% (122/336)
回答No.1

ajaxを使っていない前提で回答します。 ページが変わる地点で前にチェックしたID番号を覚えておかなければなりません。 そうするにはGETでURLに書くか、 POSTでhiddenに持たせるか、 SESSIONで持たせるかしかありません。 sessionは管理が面倒なので、私ならGETでIDを持たせます。 一番いいのはajaxとjqueryを使うことではありますが。

関連するQ&A

  • mysql limitページ分割

    前の人が質問したのを参考にしてつくったのですがうまくいかず困っています 検索結果を10件ずつ表示して googleみたいに 1l 2l 3 みたいな感じやりたいです <html> <body> <?php //データベースに接続 if (!$con = mysql_connect("localhost", "root", "admin")) { echo "接続エラー" ; exit ; } //データベースを選択 if (!mysql_select_db("db_test", $con)) { echo "データベース選択エラー" ; exit ; } //LIMITを使ったSELECT文を作成 $sql = "select * from tbl_test where (氏名 LIKE '%{$_POST['name']}%') or (住所 LIKE '%{$_POST['name']}%')"; $sql = "limit" . $page_num*10 . ", 10" ; //SQL実行 if (!$res = mysql_query($sql)) { echo "SQLエラー<BR>" ; exit ; } //検索結果表示 echo "<table border=1>" ; echo "<tr> <th>番号</th> <th>氏名</th> <th>住所</th> <th>操作</th> </tr>" ; while($row = mysql_fetch_array($res)){ $ID = htmlspecialchars($row['番号']); $NAME = htmlspecialchars($row['氏名']); $ADDR = htmlspecialchars($row['住所']); echo "<tr> <td>$ID</td> <td>$NAME</td> <td>$ADDR</td> <td><a href='edit.php?番号=$ID'>修正</a> <a href='delete.php?番号=$ID'>削除</a></td> </tr>"; //検索条件に該当する全データの件数取得 $sql = "select count(*) from tbl_test " ; $sql = "where (氏名 LIKE '%{$_POST['name']}%') or (住所 LIKE '%{$_POST['name']}%')"; if (!$res = mysql_query($sql)) { echo "SQLエラー<BR>" ; exit ; } $row = mysql_fetch_array($res) ; $cnt = $row[0] ; //ページ表示 if(!$cnt > 10) echo ceil($cnt / 10), "ページの中の", $page_num + 1, "ページ目を表示<br>" ; //前の10件 if ($page_num != 0) { echo "<a href = find.php?name=",$name, ", $page_num -1.">" ; echo "&lt 前の10件"; } //次の10件 if (($page_num + 1)*10 < $cnt) { echo "<a href = find.php?name=",$name, ", $page_num +1.">" ; echo " 次の10件 &g</a>t" ; } //結果セットの開放 mysql_free_result ($res) ; //データベースから切断 mysql_close($con) ; ?> </body> </html> Parse error: syntax error, unexpected '前の10件' (T_STRING), expecting ',' or ';' というエラーが出て自分なりにバグを消しているのですがまだエラーが消えずに困っています

    • ベストアンサー
    • MySQL
  • MySQLのLIMITで指定通りに取得できない原因

    PHPとMySQLについて勉強しています。 ページ制御で各ページのボタンを押すと、 MySQLのLIMITで何番目~何番目のデータを取得して 表示させるものを作ってみたいと思っています。 作ったコードはこちらにあります。 PHP https://box.yahoo.co.jp/guest/viewer?sid=box-l-co4ivitvpdo32iqddqwd3piwfi-1001&uniqid=f76637ed-5a9b-4eff-8b84-b4c74045a0e6&viewtype=detail MySQL https://box.yahoo.co.jp/guest/viewer?sid=box-l-co4ivitvpdo32iqddqwd3piwfi-1001&uniqid=fdeb7fdb-3969-4a60-bbdc-3142d0982c9e&viewtype=detail $mysql_Code_Limit = $mysql_Code." LIMIT ".$limit_start.",".$limit_end; でecho $mysql_Code_Limit;とすると SELECT * FROM infotable LIMIT 0,2 や SELECT * FROM infotable LIMIT 12,14や SELECT * FROM infotable LIMIT 24,26 など ちゃんと思い通りになっているのですが、 実際に表示される内容は、 1ページ目:id1~id2:2行分取得 2ページ目:id4~id8:5行分取得 3ページ目:id7~id14:8行分取得 4ページ目:id10~id20:11行分取得 5ページ目:id13~id26:14行分取得 6ページ目:id16~id30:15行分取得 7ページ目:id19~id30:12行分取得 8ページ目:id22~id30:9行分取得 9ページ目:id25~id30:6行分取得 10ページ目:id28~id30:3行分取得 といったようにおかしくなります。 上記の特徴は、SELECT ~ Limit A , B;だとすると Aは3ずつ増加 Bは3+3増加 といった状態です。 なぜこのようなことになってしまうのでしょうか。

    • ベストアンサー
    • PHP
  • JDBC(MySQL Connector J/)でのLIMIT句について

    JDBC(mysql-connector-java-3.1.8-bin.jarを使用)にて、MySQLからデータを取得するプログラム中で、どうしても解決できない問題がありご質問させて頂きました。 初心者で申し訳ございませんがご教授お願い致します。 上記のJDBCを使ってデータ数20万件程のテーブルから select * from test_table where id>100 order by id asc limit 0,500 のような感じでデータ取得を行うと、limitが500件までに設定しているにもかかわらず、whereでの条件に適合するデータが多いと(例えばwhere id>1)クエリの実行に非常に時間がかかり、結局OutOfMemoryで止まってしまいます。OutOfMemoryで止まるということは返ってくるデータが大きすぎるのかとも思いましたが、LIMITで制限しているし、何故か分からず困り果てております。 私が仕組みを理解していないだけなのかもしれませんが、宜しければご教授頂けませんでしょうか?宜しくお願いいたします。

    • ベストアンサー
    • Java
  • データのページ切り替え表示方法を教えてください

    データを複数のページに分けて表示させたいと思っていますが、 「次のページ」「前のページ」がうまく作れないでおります。 SQL文によるクリエ結果の先頭と最後のレコードID(ユニークでIDを振っています)を取得すれば、 次のページなら SELECT * FROM table_name id > [先頭レコードID] LIMIT 10; 前のページなら SELECT * FROM table_name id < [最後レコードID] LIMIT 10; とやればいいのかなと思っていますが、クリエ結果の最初と最後のレコードIDを取得する方法がわかりません。 どうか上記の件、ご教授くださいm(_ _)mペコリ

  • MySQLで、NULLか空の判定について

    下記のSQL文は、間違っていると思われます。 MySQLをJAVAでコーディングしています。 やりたいことは、 1)food_textが、NULLか、空っぽの時に、 2)limit_dateが最大の 3)レコード1件を抽出したいのです。 SELECT Id, food_id FROM foods   WHERE    (kind_id = 1)  AND (food_text IS NULL) AND (DATALENGTH(food_text) <= 0)  AND (delete_flag = false)  ORDER BY limit_date DESC  LIMIT 1;

    • ベストアンサー
    • MySQL
  • 【MySQL5.7】IDごとの最頻値

    お世話になります。MySQLでidごとの最頻値を抽出しているのですが、 select id, hantei,count(*) as ModeCount from member a group by id,hantei having count(*) >= all(select count(*) from member b where b.id=a.id group by hantei asc) order by id,hantei レコード数は5000件ほどなのですが現在の方法では10.485sと時間がかかりすぎて困っています。MySQLでは最頻値を出すのにサブクエリを使うしかないのでしょうか? こうすればもっと速くなるよって方法があれば教えてください。お願いします。

    • ベストアンサー
    • MySQL
  • MySQLでデータ表示

    MySQLでデータの表示を行っています 10件ずつ表示し、11件からは2ページ目に表示したいです サイトや本を見ながらデータ表示と次の10件のリンクは表示されるよう自力で頑張ったのですが 次の10件を押してもデータが変わらず1件目から10件目のままです どこが違うか教えてもらえますか。 どうコードを入力するか教えてくれたらありがたいです 一覧 ta2.phpです <html> <body> <form action = "ta2.php" method="GET"> <input type="hidden" name="page" value="0"> </form> <?php //データベースに接続 if (!$con = mysql_connect("localhost", "root", "admin")) { echo "接続エラー" ; exit ; } //データベースを選択 if (!mysql_select_db("db_test", $con)) { echo "データベース選択エラー" ; exit ; } //LIMITを使ったSELECT文を作成 $sql = "select * from tbl_test" ; $sql.= " limit " . $page*10 . ", 10" ; //SQL実行 if (!$res = mysql_query($sql)) { echo "SQLエラー<BR>" ; exit ; } //検索結果表示 echo "<table border='1'> <tr> <th>番号</th> <th>氏名</th> <th>住所</th> <th>操作</th> </tr>"; while($row = mysql_fetch_array($res)) { $ID = htmlspecialchars($row['番号']); $NAME = htmlspecialchars($row['氏名']); $ADDR = htmlspecialchars($row['住所']); echo "<tr> <td>$ID</td> <td>$NAME</td> <td>$ADDR</td> <td><a href='edit.php?番号=$ID'>修正</a> <a href='delete.php?番号=$ID'>削除</a></td></tr>"; header('content-type: text/html; charset="utf-8"'); if ($_GET) { // データがGETされていたら $page = isset($_GET['page']) ? $_GET['page'] : ''; // 取得 } } $sql = "select count(*) from tbl_test " ; if (!$res = mysql_query($sql)) { echo "SQLエラー<BR>" ; exit ; } $row = mysql_fetch_array($res) ; $cnt = $row[0] ; //ページ表示 if(!$cnt > 10) echo ceil($cnt / 10), "ページの中の", $page + 1, "ページ目を表示<br>" ; //前の10件 if ($page != 0) { echo "<a href = ta2.php?page= $page>" ; echo "&lt 前の10件" ; } //次の10件 if (($page + 1)*10 < $cnt) { echo "<a href = ta2.php?page= $page>" ; echo " 次の10件 " ; } //結果セットの開放 mysql_free_result ($res) ; //データベースから切断 mysql_close($con) ; ?> </table> </body> </html>

    • ベストアンサー
    • MySQL
  • mysqlでの検索方法について

    初めて質問をさせて頂きます。初心者にてどうにも行き詰ってしまいアドバイスを頂けたらと思います。 野球の打率ランキングを出したいのですが、最終的には下記の条件で抽出したいと思っております。 1位 A君 0.333 2006年 2位 B君 0.321 2008年 3位 C君 0.300 2007年 ・・・ 環境としましては、PHP4.4.4 MYSQL4.0(レンタルサーバー) テーブル record ID(INT)|選手番号(INT)|安打(INT)|打数(INT)|年度(INT)|試合番号(INT)| 1 | 1 | 1 | 1 | 2008 | 10 | 2 | 1 | 0 | 1 | 2008 | 10 | ・・・ というように、選手の1打席毎にレコードがあります。 また規定打数を試合数×3.1と設けて、その打数に達しないものは抽出しないようにしたいのです。 SELECT round(sum(安打) / sum(打数),3) as daritsu, 選手番号, 年度 FROM record GROUP BY 選手番号, 年度 HAVING sum(打数) > count(distinct(試合番号)) * 3.1 ORDER BY daritsu DESC LIMIT 0 , 10 と考えてみたものの、この場合は選手の出場試合数×3.1となってしまい、チームの試合数ではありません。行き詰っているのは、年度毎のチームの試合数に対して規定打数を設定することだと思います。 条件のような抽出が難しいようであれば、抽出後にPHPで処理という形でも構いませんので、アドバイスの程よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • MySQLでページ毎にログを取りたい

    MySQLでページ毎にログを取りたい ex) +----+------+ | id | name | +----+------+ | 01 | aaa | | 02 | bbb | | 03 | ccc | +----+------+ のようなテーブルがあったとして、id を使って動的ページを生成しています。 id は数万件あります。 そこで各 id ごと(各ページ毎)にアクセスログを取りたいのですが、 例えば1つの id につき最新10000件までのログを取るとします。 この場合、以下のように id 毎にテーブルを作成すると、当然ながらテーブル数が膨大になってしまいます。 ex) id XX のテーブル +------+----------------------------+----------+ | date | addr        | ref | +------+----------------------------+----------+ | 0000 | XXX.XXX.XXX.XXX | http://~ | | 0000 | XXX.XXX.XXX.XXX | http://~ | | 0000 | XXX.XXX.XXX.XXX | http://~ | +------+----------------------------+----------+ (10000レコードまで) テーブル数が数万というのは MySQL では珍しくないものなのでしょうか? それとももっと他に良い設計方法などあるのでしょうか? (またはこういうデータを取るのにMySQLは向いていない?) なおアクセスログとはいえ、その集めたデータを元に、利用者にアウトプットを同期して行いたいので、頻繁に参照・書込があることを想定しています。

    • ベストアンサー
    • MySQL
  • MySQL WHERE句のLIKE検索

    初心者ですみません。 MySQL WHERE句のLIKE検索で、引っかかった文字列を 除いた項目を表示させるにはどうしたらいいでしょうか。 例えば、 SELECT * from [テーブル名] where [フィールド名] like '%あ%'; として、「あ」が入っているレコードを検索し、 該当しないレコードを表示させる。 どうか教えてください。よろしくお願いします。

専門家に質問してみよう