みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Mysqlとphpでソートや更新時の効率的な処理

カラムの作成日時と更新日時のそれぞれでソート、
作成日時当日はNEWの文字を入れる。というものを作りたいと思っています。

<?php
$cer = "SELECT * FROM data_data WHERE 1";
function orderbyset($cul, $sc, &$cer){
$cer .= " ORDER BY ".$cul." ".$sc;
}

if(isset($_GET['orderby'])){
switch($_GET['orderby']){
case 'md_asc':
orderbyset('modified_date','ASC',$cer);
break;
case 'md_desc':
orderbyset('modified_date','DESC',$cer);
break;
case 'cd_asc':
orderbyset('create_data','ASC',$cer);
break;
case 'cd_desc':
orderbyset('create_data','DESC',$cer);
break;
}
}

$acc = mysql_connect(ホスト,ユーザー,パスワード);
$que = mysql_query($cer,$acc);

$html = "";
while($row = mysql_fetch_array($que)){
$id = $row["id"];
$name = $row["name"];
$modified_date = $row["modified_date"];
$create_data = $row["create_data"];
$daydiff = floor((strtotime($modified_date)-strtotime($create_data))/(3600*24));
if($daydiff==0){$datatext = 'new';}else{$datatext='';}
$html .= "<tr><td>$id</td><td>$name</td><td>$modified_date</td><td>$create_data</td><td>$datatext</td></tr>\n";
}
?>
<html lang="ja">
<head>
<title></title>
</head>
<body>
<p>更新日時順<br />
<a href="data-sort.php?orderby=md_asc">昇順</a>
<a href="data-sort.php?orderby=md_desc">降順</a>
</p>
<p>作成日時順<br />
<a href="data-sort.php?orderby=cd_asc">昇順</a>
<a href="data-sort.php?orderby=cd_desc">降順</a>
</p>
<table><?php echo $html; ?></table>
</body>
</html>

+---------------+-----------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-----------+------+-----+-------------------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(10) | NO | | NULL | |
| modified_date | timestamp | NO | MUL | CURRENT_TIMESTAMP | |
| create_data | timestamp | YES | MUL | NULL | |
+---------------+-----------+------+-----+-------------------+-------+

modified_dateの属性にはon update CURRENT_TIMESTAMPを設定し、
カラムのデータを変えるとmodified_dateが更新され、create_dataはそのままです。

SELECT id,name,modified_date,create_data,IF(`create_data`>CURDATE() - INTERVAL 0 DAY,'NEW',DATE_FORMAT(`create_data`,'%Y/%m/%d')) AS `ddd` FROM `data_data`
http://okwave.jp/qa/q3058491.htmlでの方法がありました。

$daydiff = floor((strtotime($modified_date)-strtotime($create_data))/(3600*24));
if($daydiff==0){$datatext = 'new';}else{$datatext='';}
「あるカラムの情報が変わったら○○させる」といったことをいくつか追加していきたいので、
パフォーマンスが落ちることを少しでも避けるためにphpで処理するようにしましたが、一般的にはどちらを使うものなのでしょうか。

また、ifばかりにならないようにswitchを使ったのですが、ソートもいろいろ追加していきたく、そうなると今度はswitchが多くなってしまいます。
switchやifを使わずにスマートにやれる方法はないでしょうか。

投稿日時 - 2012-06-07 01:53:24

QNo.7518982

困ってます

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

なにかへん

SQLでは作成日が今日ならNEW、PHPでは作成日が更新日ならNEW
と書かれていませんか?
今回の場合ですとNEWを抜き出すロジックはSQLで処理する意味がありそうですが
集計とちがってSQLに特段の優位性があるわけではないので、
どちらでやっても有効性に差はないでしょう

またソートも多段でおこなう必要がでてきたときにswitchは微妙ですね
多段でソートすることも想定するとこんな風にするとよいかもしれません

<a href="?o%5Bx%5D=a&o%5By%5D=a&o%5Bz%5D=a">x昇順-y昇順-z昇順</a><br>
<a href="?o%5Bx%5D=a&o%5By%5D=a&o%5Bz%5D=d">x昇順-y昇順-z降順</a><br>
<a href="?o%5Bx%5D=d&o%5By%5D=a&o%5Bz%5D=a">x降順-y昇順-z昇順</a><br>
<a href="?o%5Bx%5D=d&o%5By%5D=a&o%5Bz%5D=d">x降順-y昇順-z降順</a><br>
<a href="?o%5Bx%5D=a&o%5By%5D=d&o%5Bz%5D=a">x昇順-y降順-z昇順</a><br>
<a href="?o%5Bx%5D=a&o%5By%5D=d&o%5Bz%5D=d">x昇順-y降順-z降順</a><br>
<a href="?o%5Bx%5D=d&o%5By%5D=d&o%5Bz%5D=a">x降順-y降順-z昇順</a><br>
<a href="?o%5Bx%5D=d&o%5By%5D=d&o%5Bz%5D=d">x降順-y降順-z降順</a><br>

<?PHP

$orderby="";
if(isset($_GET["o"])){
$keylist=array("x"=>"xxx","y"=>"yyy","z"=>"zzz");
$vallist=array("a"=>"asc","d"=>"desc");
foreach($_GET["o"] as $key=>$val){
if(!in_array($key,array_keys($keylist)) or !in_array($val,array_keys($vallist))) continue;
if($orderby!=="") $orderby.=",";
$orderby.=" `".$keylist[$key]."` ".$vallist[$val];
}
if($orderby!=="") $orderby="ORDER BY ".$orderby;
}
print $orderby;
?>

投稿日時 - 2012-06-07 10:56:40

お礼

有難うございます。多段の場合の処理方法、とても参考になりました。
実現したいのは多段ではないですが、覚えておきます。
名前、番号、など計5種類くらいをソートしたいです。

> o%5Bx%5D=d&o%5By%5D=a&o%5Bz%5D=d
o[x]=d & o[y]=a & o[z]=d こういうことですか。
特殊な文字を使うメリットってなんですか?

>SQLでは作成日が今日ならNEW、PHPでは作成日が更新日ならNEW
>と書かれていませんか?
更新日にしていたところをdate("Y-m-d G:i:s")にしてみました。
前回は日単位でしたが、data()だと秒単位で計算されるのですね。
このやり方が一般的ですか?

アドバイスを参考にさせていただき、改善1と2をやってみました。
改善1はjavascriptがオフだと機能しなくなってしまいます。
改善2はjavascriptがオフのときは<noscript>でsubmitボタンを出して機能しますが、radioボタンになってしまいます。
radioボタンを使うことなくaタグで囲ってjavascript未対応でも機能すればいいですが・・・
改善1と2どちらを選びますか?

■■■改善1■■■
<input type="hidden" name="d" value="md" />
<input type="hidden" name="c" value="asc" />
javascript未対応の方には更新日時順をascで。

<?php
$cer = "SELECT * FROM data_data WHERE 1";
/*-------- PHPの改善箇所 ---------*/
if(isset($_GET['dd'])&&isset($_GET['sc'])){
$a = array("modified_date"=>"md", "create_data"=>"cd");
if(in_array($_GET['dd'], $a)){
foreach($a as $key => $value){
if($_GET['dd'] != $value) continue;
$_GET['dd'] = $key;
}
}
$cer .= " ORDER BY ".$_GET['dd']." ".$_GET['sc'];
}
/*--------------------------------*/

$acc = mysql_connect(ホスト,ユーザー,パスワード);
$que = mysql_query($cer,$acc);

$html = "";
while($row = mysql_fetch_array($que)){
$id = $row["id"];
$name = $row["name"];
$modified_date = $row["modified_date"];
$create_data = $row["create_data"];
$daydiff = floor((strtotime(date("Y-m-d G:i:s"))-strtotime($create_data))/(3600*24));
if($daydiff==0){$datatext = 'new';}else{$datatext='';}
$html .= "<tr><td>$id</td><td>$name</td><td>$modified_date</td><td>$create_data</td><td>$datatext</td></tr>\n";
}
?>
<html lang="ja">
<head>
<title></title>
</head>
<body>
<form name="formname" method="GET" action="data-sort-jssubmit.php">
<input type="hidden" name="dd" value="md" />
<input type="hidden" name="sc" value="desc" />
</form>
<script type="text/javascript">
function sortchange(d,c){
var frm = document.forms['formname'];
frm.dd.value = d;
frm.sc.value = c;
frm.submit();
}
</script>
<p>更新日時順<br />
<a href="javascript:sortchange('md','desc');">新着順</a>
<a href="javascript:sortchange('md','asc');">古着順</a>
</p>
<p>作成日時順<br />
<a href="javascript:sortchange('cd','desc');">新着順</a>
<a href="javascript:sortchange('cd','asc');">古着順</a>
</p>
<table><?php echo $html; ?></table>
</body>
</html>


■■■改善2■■■
<?php
$cer = "SELECT * FROM data_data WHERE 1";
/*-------- PHPの改善箇所 ---------*/
if(isset($_GET['order'])){
list($d, $order) = explode("_", $_GET['order']);
$a = array("modified_date"=>"md", "create_data"=>"cd");
if(in_array($d, $a)){
foreach($a as $key => $value){
if($d != $value) continue;
$data = $key;
}
}
$cer .= " ORDER BY ".$data." ".$order;
}
/*--------------------------------*/

$acc = mysql_connect(ホスト,ユーザー,パスワード);
~この間は前回・改善1と同じです~
$html .= "<tr><td>$id</td><td>$name</td><td>$modified_date</td><td>$create_data</td><td>$datatext</td></tr>\n";
}
?>
<html lang="ja">
<head>
<title></title>
</head>
<body>
<form method="GET" action="data-sort-nametouitsu.php">
<p>更新日時順<br />
<input type="radio" name="order" value="md_desc" onclick="sortchange(this.form)" <?php if(isset($_GET['order']) && $_GET['order']=='md_desc') {echo 'checked ';} ?>/>新着順
<input type="radio" name="order" value="md_asc" onclick="sortchange(this.form)" <?php if(isset($_GET['order']) && $_GET['order']=='md_asc') {echo 'checked ';} ?>/>古着順
</p>
<p>作成日時順<br />
<input type="radio" name="order" value="cd_desc" onclick="sortchange(this.form)" <?php if(isset($_GET['order']) && $_GET['order']=='cd_desc') {echo 'checked ';} ?>/>新着順
<input type="radio" name="order" value="cd_asc" onclick="sortchange(this.form)" <?php if(isset($_GET['order']) && $_GET['order']=='cd_asc') {echo 'checked ';} ?>/>古着順
</p>
<noscript>
<input type="submit" name="order" value="送信" />
</noscript>
</form>
<script type="text/javascript">
function sortchange(frm){
frm.submit();
}
</script>
<table><?php echo $html; ?></table>
</body>
</html>

投稿日時 - 2012-06-08 01:29:40

ANo.1

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

>o[x]=d & o[y]=a & o[z]=d こういうことですか。
>特殊な文字を使うメリットってなんですか?

PHPにパラメータを渡す上では多用されるテクニックですが
o[x]=d&o[y]=a&o[z]=d
で渡せば、$o=array("x"=>"d","y"=>"a","z"=>"d")という処理が
自動で処理されるのでかなり楽です

別の渡し方であればo=x_d+y_a+z_dみたいな処理でもよいですが
分解する処理が冗長になりがちです

改善の件については、好き嫌いがあるのでなんともいえませんが
作成日順と更新日時は同時にソートする必要はなさそうなので
それぞれ、昇順-降順-なにもしない、の3つの選択肢にした方がよいかも
ラジオボタン

投稿日時 - 2012-06-08 09:53:10

お礼

もの凄く勉強になりました。
本当にありがとうございました。

こちらの質問文に画像の扱いを加えたものを試してみました。
見て頂けたらうれしいです。
http://oshiete.goo.ne.jp/qa/7522710.html

投稿日時 - 2012-06-09 03:03:01

あなたにオススメの質問