上から何番目か知る方法とは?

このQ&Aのポイント
  • 上から何番目か知る方法や、特定のレコードを取得する方法について解説します。
  • SQLを使用して特定のレコードを時間でソートし、上から何番目かを知ることができます。
  • PHPを使用してソートされたレコードを取得し、希望のナンバーまでのレコードを表示する方法もあります。
回答を見る
  • ベストアンサー

上から何番目か。

$sql = "select * from table_namae where no = 115 order by jikan desc"; の場合、上から何番目か知る方法がわからん。 時間でソートして、そのnoが上から何番目かを知りたい。 もちろん、レコードの値も欲しい。 NO 115を検索して  タイトル 名前 パスワード  → 時間でソートして上から?番目 noはPRIMARYで重複する値はなく常に一つだけ。 SQLで値を得る事は、無理? noは特にその都度変わるので、limitは使えないと思うんですが。 PHPなら、ソートして最初から希望のナンバーまでのレコードを取得。 $i = 0;  while($col = mysql_fetch_array($rst)){$i++; if(希望のナンバー){ print "$i番目"; print "タイトル、名前さん。"} } これでも、取得できるけど、無駄なループになるし。

  • MySQL
  • 回答数5
  • ありがとう数8

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

  • ベストアンサー
回答No.3

ちょっと、タイプミスが、 SELECT T1.no, T1.name, T1.title, T1.jikan, COUNT(T2.no) as bangou FROM table_namae as T1, table_namae as T2 WHERE T1.no = 115 AND T1.jikan >= T2.jikan GROUP BY T1.no; こっちです。 質問の意図を読み間違えてなければ、これでばっちり。

to-zoku
質問者

お礼

いろいろといじった結果。 挙動の内容が分かりません。 いや、結果はokなンすけど。 SELECT T1.no, T1.name, T1.title, T1.jikan, //上記のフィールドを表示させる COUNT(T2.no) as bangou //bangouをカウントする  //↑なにをカウントしてる? //理屈としては、T1.jikan >= T2.jikanの場合はカウントしてるんだろうけど //と、言う事はループしてる?どこが?なにが? //COUNT(*)としないのは、重さ軽減のため? FROM table_namae as T1, table_namae as T2 //テーブルをT1,T2とする WHERE T1.jikan >= T2.jikan //T1.jikan >= T2.jikan を比較ループしてる? //WHERE文って、ループしないですよね? //検索上から下まで1回では、無理な気もします。 GROUP BY T1.no //GROUPでまとめる ORDER BY bangou; //bangou順にソート WHERE T1.jikan >= T2.jikanで抽出して、COUNT(T2.no)してるんだろうけど、SQL側の挙動が最終的に分かりません。 本来の問題は解決しているのですが、知識のある方どなたでもいいので、教えて頂けると、すっごい助かります。^^;

その他の回答 (4)

回答No.5

付き合ったついでに・・・ SQLを考えるときには、ループなどで考えてはいけません。 集合的に考えると話がすっきりします。 まず、FROMに書かれている全てのテーブルの直積(組み合わせ)を考えます。 この例だと、T1とT2の全ての行の組み合わせです。 行数は、テーブルの行数を全て掛け合わせたものになります。 次にWHEREの条件で行を絞り込みます。 次にGROUP BYで書かれた項目でグルーピングを行います。 その結果行をHAVINGで絞り込みます。 最後にORDER BYで並べ変えます。 COUNT(T2.no)はCOUNT(*)でもかまいません。 ほとんど同じ意味です。 本人はあまり意識しないで書いてます。 この例では、noは主キーですので、NULLは入っていないでしょうから、同じ値になりますね。 COUNT(no) は、noがNULLの行を数えないのに対し、COUNT(*)は、全てを数えると言う違いがあります。

to-zoku
質問者

お礼

直感的に分かったのが、”集合的”という言葉です。 「テーブルの行数を全て掛け合わせたものになる。」 なるほど、これでおぼろげながらSQLのデータ構造が分かった気がします。 WHEREの条件、GROUP BY、HAVING、ORDER BYの順番も参考になりました。 まだ、SQL文も手探りで、とりあえず作成。 ダメなら、位置を変えてみたり別の記述を試してみたり、結果を眺めてあってそうなら理由を考える。 okそうなら、PHPに書くという手順です。 本当にありがとうございました。^w^

回答No.4

T1のnoを115にしてますので、T1からは、noが115の行だけが、抽出されます。 T2は、T1のnoよりnoが小さいか等しい行だけが、抽出されます。 したがって、GROUP BYを行う前は、T1のnoが115の行と、T2のnoが115以下の行が存在します。 T1.no T1.name T1.title T1.jikan (T2.no) T2.jikann 115 foo var 110 1 10 115 foo var 110 40 50 115 foo var 110 115 60 T2.name と T2.title は関係ないので省略しています。 これを、T1.no でグループ化すると、答えが出ます。 T1.no は、グループ化項目なので関係なし、T1.name、T1.title、T1.jikanは、全行で同じなので問題無しです。 T2.noは表示しないので、これも問題ありません。 これで、分かりました?

to-zoku
質問者

お礼

まだ説明はできませんが、感覚的に分かったような気がします。 PerlやPHPとは、SQLは一線を画しているンすね。 当たり前か。^^; 毎回、フィーリングでプログラムを作っているンすけど、(たぶんこの方が処理が早い、メモリー的にも少ない、、、はず)、こういう細かな設定やシステムには、気になってしまって。 大変参考になりました。 ボクのSQLの礎の一つとなると思います。

回答No.2

こんなSELECT文で書けます。 SELECT T1.no, T1.name, T1.title, T1.jikan, COUNT(T2.no) as bangou FROM table_namae as T1, table_namae as T2 WHERE T1.no = 115 AND T1.jikan >= T2.jikann GROUP BY T1.no;

to-zoku
質問者

お礼

やっぱり、すごい人もいるものです!! できました。 このスクリプトでは一行だけでなく、T1.no = 115 AND をはずせば、すべての上からの番号が表示できます。 この文は、あと半年くらいはボクには書けそうもありません。 GROUP BYか、Havingかいろいろ試してはみたのですが、うまくいきませんでした。 テーブル名に仮の名前を付けて比較する事もできるんですね。 大変参考になりました。

  • moon_night
  • ベストアンサー率32% (598/1831)
回答No.1

PHPと絡めますが、 $sql = "select * from table_namae where no <= 115 "; $rst = mysql_query($sql); $rows = mysql_num_rows($rst); とすれば数が出てきますね。

to-zoku
質問者

補足

mysql_num_rowsで出るのは、配列の総数。 私が知りたいのは、 no□name□title□jikan 1□一太郎□最初に□110 2□次郎□次ぎに□160 3□佐武郎□三番□95 で、時間でソートしたもののnoの上からの何番目という事です。 ソートすると、こうなります。 3□佐武郎□三番□95 1□一太郎□最初に□110 2□次郎□次ぎに□160 ソートしたものをnoの1で検索すると、2番目となります。 ソートしたものをnoの2で検索すると、3番目となります。 このnoが変わった時の、上から何番目がしりたいのですが。 mysql_num_rowsだと、3が出ます。 3つくらいなら、すべてを読み出してループしちゃえばいいんだけど、MySQLで分かれば、その方が早いかと。 ないですかね?

関連するQ&A

  • MySQLで一番最後のレコードをしる関数って?

    MySQLで一番最後のレコードを知る関数ってありますか? noや時間情報のソートの最初の値ではなく、簡単に最後に追加したレコードを取得する方法。 ないなら、方法としてはレコード数をカウントして、全カウント数番目をselectすればいいんでしょうか? SQLには、最後とかの概念がないかな?

    • ベストアンサー
    • MySQL
  • 一行目のレコードを2度表示させたい。

    レコードを読み込むのとは別に、最終書き込み者(ソートした最初のレコード)を表示させたいのですが、mysql_fetch_array($rst)を読み込ませると1位行目が消え、次ぎにmysql_fetch_array($rst)が読み込む時には2行目からになります。 ------------------------- 最終書き込み者 一太郎さん「一番目のタイトル」 -レコードの一覧- □一太郎 一番目タイトル □次郎  2番目のタイトル □佐武郎 三番目のタイトル ------------------------- としたいのですが。 SQLを2度実行すればできるのですが、無駄な処理な気もします。 別のテーブルやこの情報だけtextに保存するのも無駄な気もするし。 //一番目をゲット $sql = "select * from siritori order by db_no desc limit 1;"; $rst = mysql_query($sql,$con); //$rst2 = $rst; $col = mysql_fetch_array($rst); print "最終書き込み者".$col["name"]."さん".$col["title"]."<hr>"; //一覧を表示 $sql = "select * from siritori order by db_no desc limit 10;"; $rst = mysql_query($sql,$con); //SQL配列読み込み(select文) while($col = mysql_fetch_array($rst)){ print $col["name"]."さん".$col["title"]."<br>".$col["kome"]."<hr>";} //$rst2 = $rst; 配列をコピーできないかなー?とかもやったのですができない。 なんとか巧い解決方法はないでしょうか? 連想配置や、MySQLには詳しくないのでお教えください。

    • ベストアンサー
    • MySQL
  • PHP変数にXMLのタグ内容を代入するには?

    ■質問内容: 超初心者です。質問が的外れかもしれませんが自己解決できずにいます。何卒ご教授ください。 達成したい内容としてRSS生成をPHPで作成中です。 PHPの $hensu1 = 別ファイルXMLにある<namae>名前</namae>の"名前" を代入したいのですが記述方法が解らず、困っております。 そのほかの質問もありますが、後述します。 ■環境: php:4.3.** (ホスティングの為、サーバの設定変更などできません) ■状況と経緯: 実際のコードを乗せます。 直接ご指摘いただけると、大変ありがたいです。 【rss.php】 <?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?> <? $hensu1 = "(1)別ファイルXMLにある<namae>名前</namae>の"名前" を代入したい"; $hensu2 = "(2)別ファイルXMLにある<nedan>100円</nedan>の"100円" を代入したい"; $pubjikan ="(3)別ファイルXMLにある<jikan>2009/02/26-17:50</jikan>の"2009/02/26-17:50"を代入したい" ?> <rss version="2.0"> <channel> <title >タイトル</title> <link>http://local/</link> <description>webページ</description> <language>ja</language> <copyright>会社</copyright> <managingEditor></managingEditor> <webMaster></webMaster> <pubDate>Thu, 26 Feb 2009 00:00:00 +0900</pubDate> <lastBuildDate></lastBuildDate> <item> <title>タイトルは<? echo "[ {$hensu1} ]"; ?>です</title> <link>books.xml</link> <description>価格は<? echo "[ {$hensu2} ]"; ?>です</description> <pubDate><? echo $pubjikan; ?></pubDate> ←(4)ここは日付を成型するPHPを記述したいの </item> ~(5)ここに、XMLから繰り返し取得したい(最大5件程度)~ </channel> </rss> --- 【books.xml】 <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="table.xsl"?> <books xml:space="default"> <book no="000">  <namae>名前</namae> <nedan>100円</nedan> <jikan>2009/02/26-17:50</jikan> </book> <book no="000"> ←(5)に該当。以降を繰り返し5件程度取得したい。 <namae>名前2</namae> <nedan>200円</nedan> <jikan>2009/02/25-19:30</jikan> ~ ~繰り返し数十件のデータあり ~ </book> </books> --以上-- 上記の(1)~(5)について教えてください。 出来れば具体的な記述でご指摘いただけるか参考サイトをご紹介 下さるとありがたいです。 Domxmlなど自分なりに見当つけてみましたが、上手くいきませんでした。 何卒、宜しくお願いいたします。

    • ベストアンサー
    • PHP
  • SQLによる"あいうえお"順でソートする表記方法とは?

    VBでSQLを使用するのですが、 とあるリストをあいうえお順で取得したいのです。 SQLによる"あいうえお"順でソートする表記方法とはどのようにすればよいのでしょうか?

  • 同じテーブル内の各CD、DATEごとの1番目レコードの抽出方法

    SQLについての質問です。 同じテーブル内の各CD、DATEごとの 1番目レコードの抽出方法がわかりません。 (CD、DATEでソート) テーブル名:TMP CD DATE KIN 1 2007/09/01 5555 1 2007/09/01 2000 1 2007/09/01 3000 2 2007/09/05 2222 2 2007/09/05 3333 3 2007/09/10 9999 抽出結果(CD、DATEでソート) 1 2007/09/01 5555 2 2007/09/05 2222 3 2007/09/10 9999 どのようにすると抽出できるのでしょうか? よろしくお願いいたします。

  • CSVデータのn番目だけの値を取得したい

    次のCsvファイルがあります。この2番目の列の値(つまり20,35,58・・・)だけを取得(1次元配列に入れる)したいのです。 ,cosmos,himawari 710,20,106 725,35,131 805,58,175 820,97,180 903,110,180 次のようにしましたが、2番目の値だけの抽出が出来ません。どのように直せば良いでしょうか? <?php $TextData = file("./cosmos.csv"); for($i=0; $i<10; $i++){ $cosmos = $TextData[i][cosmos]; } return $cosmos print_r($cosmos); ?> 出力結果 Array ( [0] => ,cosmos,himawari [1] => 710,20,106 [2] => 725,35,131 [3] => 805,58,175 [4] => 820,97,180 [5] => 903,110,180 )

    • ベストアンサー
    • PHP
  • [ACCESS97]SQLの書き方

    グラフのレコードソースにクエリ・SQLを使用しています。データ入力チェックに使おうと思っています。妙なデータがはいった場合、グラフが乱れるのではないかと。 ソートは日付でしています。 それで、100レコードずつを順番に表示していきたいのですが、top値 だと最初からいくつ、、としか指定できません。これを、レコードの途中の任意の位置から取るにはどうしたらいいのでしょうか? IDとかのようにユニークな値でソートしているのであれば、大小関係で一発ですが、同じ値がいくつも存在する日付なもので困っています。 日付でソートしたものを配列に入れる、もしくは一度テーブルに書き出す等も考えているのですが、SQLでできたら助かります。 よろしくお願いします。

  • ある値以上の空き番の最小値を取得するSQL

    テーブル TB の項目 CDがNUMBER型でユニークキーだとします。 このCDで ・ある値以上の空いている最小の番号を取得したい。 としたら1つのSQLで実現できますか? 例) CDの値が 6・・・・80 150・・・ (81から149は存在しない) という具合に存在していた場合に、101以上で空いている最小の番号 を取得したいのです。 この場合は101です。1が取得されても駄目、81が取得されても駄目です。 また、同じ条件でデータが 6・・・・150 200・・・ (151から199は存在しない) の場合には151が取得したいのです。 このような値を検出するSQLってわかりますか? 以上よろしくお願い致します。

  • 掲示板の表示について

    掲示板を作っています。 書込みなどの表示がうまくいかず困っています。 試行錯誤していますが、うまくいきません。 下記のように表示したいのですが、 タイトル.ああ               名前.いい 記事NO.うう 下記のように表示されてしまうのです。 タイトル.ああ いい うう 名前.ああ いい うう 記事NO.ああ いい うう 問題のソースは以下の通りです。 <?php $data = file("../php/test1.txt"); list($title, $namae, $body) = explode("\t", $data); for($i=sizeof($data)-1;$i>=0;$i--){ print "タイトル.${data[$i]}<br>\n名前.${data[$i]}<br>\n記事NO.${data[$i]}<br>\n<hr>"; } ?> どなたかおわかりの方いましたらお願い致します。

    • ベストアンサー
    • PHP
  • DBを使用しないで条件にマッチしたもののみページング

    以前DBを使用しないページングについてお教えいただいた者です。 少し改良して降順ソートを出来るようになったのですが、 リスト表示の際にある条件に一致したもののみを表示する場合の やり方が分かりません。。。 現在は以下のようになっています。 ■sample.csv no0001,あああああ,20050101,ON no0002,いいいいい,20050102,OFF 略) no0020,ととととと,20050120,OFF ■index.php (800字オーバーしてしまうので、省略しています。) //ファイルを配列に格納 $rec = file("sample.csv"); //レコード数を取得して、最後尾の行番号を取得 $rec_number = sizeof($rec) -1; //ページ範囲を出力 for ( $i = $rec_number-$page*$max; $i > $rec_number-$page*$max-$max; $i -- ) { $data = explode(",","$rec[$i]"); if ($data[3]==("ON") && $data[2]<=date("Ymd")) { print $data[0].("<br>"); print $data[1].("<br>"); print $data[2].("<br><br>\n"); } } print "<a href=\"?page=".($page+1)."\">次のページへ</a>\n"; ?> CSVの各行の[3]が 「ON」となっていれば表示し、 「OFF」となっていれば表示しないようにし、 また、[2]が 今日以降の日付であれば表示しないようにしたいのですが、 for文の中に上記のようなif文を使ってしまうとオカシナことに なってしまいます。 (no0020が抜けただけで1ページ目に9件しか表示されません。本当は no0020が抜けたので、no0010までの10件を表示させたいのです。) 根本的な部分が間違っているような気がするのですが、 どのような考え方で作れば良いのか分かりません。 また皆様のお力をお貸しください。 宜しくお願いします。

    • ベストアンサー
    • PHP