• ベストアンサー

ソートした際の、特定のデータの番目を出したい

例として、id,count というフィールドを用意し、下記のようなデータを使用します。 id count A 5 B 2 C 3 このデータから、Aは ORDER BY count DESC で何番目なのか、Bは、Cは、といった形で、各々が何番目なのかを取得することは可能ですか? また、可能でしたらどのような方法が考えられるでしょうか。 単純な例で言うと count で降順にソートした際の、id A と id C の番目を取得したい。 (Aは0・Cは1、番目が1からの場合 Aは1・Cは2といったデータ) といったピンポイントでピックアップしていくような使い方をしたいと思っています。 また、取得後はPHPでデータを利用します。 少ないデータなら、全てのデータを取得してからPHPで振り分けも可能ですが、大量のデータがある際に効率的にできないかと質問させていただきました。 よろしくお願い致します。 ----------------- 環境  PHP 5.2.5  MySQL 5.1.22

  • atse
  • お礼率73% (17/23)
  • MySQL
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • yone_sk
  • ベストアンサー率34% (58/167)
回答No.1

行番号を取得できれば ------------------------ SELECT ROW_NUM FROM (SELECT [行番号] AS ROW_NUM, * FROM [テーブル] ORDER BY [ソート順]) WHERE id in ('A', 'C') ------------------------ こんな感じでできると思いますが、 雰囲気つかめますでしょうか。 MySQLでの行番号の取得方法がわかりませんでした・・・orz (oracle なら ROW_NUMBER関数 で取得できるのに・・・) 試してませんが [行番号] を COUNT(id) + 1 にしてできませんかね^^;

atse
質問者

お礼

ありがとうございます。 行番号というキーワードをもとに調べ、 当方の環境でoracle の ROW_NUMBER関数と同じ動作をさせるには、 変数を用意して自前で行番号を作るというのがありました。 試したのは以下です SET @ROW_NUM = 0; SELECT (@ROW_NUM:= @ROW_NUM + 1) AS ROW_NUMBER , `id`,`count` FROM `test` WHERE id in('A','C') ORDER BY `count` DESC; これでA->1 C->2という結果が得られ、成功したと思ったのですが、 この番号は、どうやらソートだけに対しての番号ではなく、 WHERE節 も含んだ結果の番号になっていました。 ですので、WHERE id in('A','B')としても A->1 B->2 となってしまいます。 WHERE id in('A','B')の際に取得したいデータは A->1 B->3 というデータ(ソートされた際の順番)なのですが、 oracle の ROW_NUMBERですと、WHERE節を含まず得られますか? TEMPORARY TABLEを使用して一度行番号を付けたテーブルを作成しそこからWEHER節を使うという方法もやってみましたが、 こちらも大量のデータを扱うとなると、効率・負荷的にどうなのかと疑問に思ってしまいました。 また、最初から行番号を付ける事も考えましたが、後からデータを一部削除することもあるので、番号のずれを直すのも手間になると思いやめました。 助言・ご教示いただければ幸いです。

その他の回答 (1)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.2

同順位がでたときに、繰り上げるか繰り下げるかで処理がことなります。 つまり、5のデータがあったとき3位が同順位だった場合、繰り下げなら「1,2,3,3,5」になり、繰り上げる場合は「1,2,3,3,4」となります。 仮にhogeテーブルに対して、普通に繰り下げる場合は SELECT (SELECT COUNT(*) +1 FROM hoge AS H2 WHERE H2.count < H1.count) AS RANK ,`H1`.* FROM hoge AS H1 となります。 これにWHERE id='A'とかつければよいでしょう。

atse
質問者

お礼

無事復旧しました。 実行時間が長かっただけだったかもしれません。 比べたところ、CREATE TEMPORARY TABLEで番号の付けた一時テーブルを作る方法が 当方の使用しているデータには最適ということがわかりました。 (抽出に0.1秒かかりませんでした) ですので、そちらを利用したいと思います。 繰り下げ等のご考慮ありがとうございました。 (当方が実際に使用したかったのも同順位無しの内容です) 最後に、最終的な内容を以下に記述し、閉めたいと思います。 SET @ROW_NUM = 0; CREATE TEMPORARY TABLE `TEMP` SELECT (@ROW_NUM:= @ROW_NUM + 1) AS ROW_NUMBER , `test`.* FROM `test` ORDER BY `count` DESC; SELECT * FROM `TEMP` WHERE id in('A','B')

atse
質問者

補足

ありがとうございます。 サーバー側でPhpMyAdminから1万数千件くらいのデータに使用してみたところ、 最後に条件を付けてみても数秒かかってしまいました。 条件無しならどんくらいかかってしまうかと思い試してみたところ 負荷をかけすぎかサーバーのPhpMyAdminが機能しなくなってしまいました。 これから復旧に向け手立てを考えるので、 もう少し検証に時間がかかってしまいますのでご了承下さい。 (こんなことは初めてなので、どう復旧させるかも1からですが・・・)

関連するQ&A

  • 区分ごとに2番目に新しいデータを取得するには?

    下記のようなデータがあった場合、それぞれの区分毎に年月が最新のデータと2番目に最新のデータを取得したいです。 <検索対象データ> 区分 年月   金額 ----------------------------- A   200411  700 A   200412  600 A   200503  560 B   200311  600 B   200508  1000 B   200504  560 C   200508  400 C   200301  1100 <取得したいデータ> (1)区分ことに年月が最新のデータ 区分 年月   金額 ----------------------------- A   200503  560 B   200508  1000 C   200508  400 (2)区分ことに年月が2番目に最新のデータ 区分 年月   金額 ----------------------------- A   200412  600 B   200504  560 C   200301  1100 (1)に関してはこちらに回答があります。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=1439772 (2)のデータを取得する方法を教えていただきたい。 (1)と(2)の混在でもかまいません。 よろしくお願いします。

  • MySQLで特定のグループの上位3件を取得したい。

    ちょっと壁に当たったので、わかる範囲でお答え頂きたいのですが、 以下のようなテーブルがあったとします。 id user price date 1 A 1000 2013/5/31 2 A 1200 2013/6/1 3 B 1000 2013/5/20 4 A 1500 2013/5/12 5 C 1300 2013/5/31 6 C 1400 2013/5/14 7 C 1000 2013/5/6 8 B 1100 2013/5/24 9 B 1200 2013/5/30 10 B 1100 2013/5/4 11 A 1800 2013/4/12 12 C 900 2013/4/6 ・・・ 次に取得したいのは、 A 1200 2013/6/1 A 1000 2013/5/31 A 1500 2013/5/12 C 1300 2013/5/31 C 1400 2013/5/14 C 1000 2013/5/6 B 1200 2013/5/30 B 1100 2013/5/24 B 1000 2013/5/20 このようなデータなのですが、 条件: 1.userでグループ化したうちの日付降順で並べる 2.そのuserのデータの中で、日付降順で並べる 3.userのデータが複数あっても、取得するのは新しいものから3件のみ この条件を満たすSQL文はどのように記述すればよいか、お知恵をお貸し下さい。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • 配列のソート

    下記のような形でデータを取得し結果を配列に格納し、 降順にソートしたいのですが、いい方法が見つかりません。いい方法はあるでしょうか。よろしくお願いします。 テーブル構造(test) ID|name |point|area| ==================== 1 |Aさん|56 | A | 2 |Bさん|12 | B | 3 |Cさん|24 | B | 4 |Dさん|34 | B | $sql = "select * from test"; $result = mysql_query($strSQL); while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) { ここで配列に格納 } 配列への格納方法と、pointの降順にソートする 方法が知りたいです。 最終的に、Aさん、Dさん、Cさん、Bさんと なるようにしたいです。

    • ベストアンサー
    • PHP
  • テーブルのどちらかにデータがない事があるテーブル結合について

    ■table a のテーブル構成 date a_id b_id c_id a_count ■table b のテーブル構成 date a_id b_id c_id b_count value 上記の2つのテーブル構成から、 ■date a_id b_id c_id毎の集計データ date a_id b_id c_id a_count b_count value を抽出するSQLが知りたいです。 table aにあって、table bに存在しない。又は逆もある為、 union しかないと思うのですが、思いつきません。。

    • ベストアンサー
    • MySQL
  • 配列データのソートについて

    配列データのソートについて 配列データAAA(1000,10)があるとします。 このデータを5番目のデータにて降順にソートしたいと考えています。 現在、次の方法にて実施していますが、効率が悪いようなので、効率の良い方法を教えて下さい。 Sheets("荷捌場").Select Range(Cells(1, 1), Cells(1000, 10))="" For A=1 To 1000 For B=1 To 10 Cells(A,B)=AAA(A,B) Next B Next A Range(Cells(1, 1), Cells(1000, 10)).Select Selection.Sort Key1:=Range("E1"), Order1:=xlDescending For A=1 To 1000 For B=1 To 10 BBB(A,B)=Cells(A,B).Value Next B Next A Sheets("ソート後のデータ貼付場").Select For A=1 To 1000 For B=1 To 10 Cells(A,B)=BBB(A,B) Next B Next A

  • SELECT/別テーブルのレコード数も取得したい

    ■環境 ・MySQL ■前提 ・テーブルA … idカラム ・テーブルB … A_idカラム ■やりたいこと ・テーブルAデータを取得する際、テーブルAレコードに応じて、テーブルB「A_idカラム」の数(レコード数)も取得したい ■取得イメージ例 ・テーブルA「全カラム」、「count」カラム ※「count」カラム … テーブルBにある「A_idカラム」の数 ■知りたいこと ・どこにも存在しないこの「count」カラムはどうやって作成したら良いでしょうか? ・全体のSQL文

    • ベストアンサー
    • MySQL
  • MSQLにおいての並び替えについて

    MySQLについての質問です。 MySQLのバージョンは4.1.20です。 テーブル +----+-------+-------+ | id | A | B | +----+-------+-------+ | 1 | 80223 | 80505 | | 2 | 80223 | 81017 | | 3 | 80410 | 0 | | 4 | 80110 | 80731 | | 5 | 80223 | 0 | | 6 | 80223 | 81223 | | 7 | 80410 | 80510 | | 8 | 80110 | 80630 | +----+-------+-------+ 並び替え後 +----+-------+-------+ | id | A | B | +----+-------+-------+ | 3 | 80410 | 0 | | 7 | 80410 | 80510 | | 5 | 80223 | 0 | | 6 | 80223 | 81223 | | 2 | 80223 | 81017 | | 1 | 80223 | 80505 | | 4 | 80110 | 80731 | | 8 | 80110 | 80630 | +----+-------+-------+ idはプライマリーキーです。 A、B共に数値(int)です。 Aには「0」という値は入りません。Bには「0」が入る可能性があります。 並び替えの条件としては 1.A 降順 2.B 0 3.B 降順 4.id 昇順 です。 イメージとしては SELECT * FROM `hoge_table` ORDER BY `A` DESC , `B` = 0 , `B` DESC , `id` ASC なのですが、結果としては、 +----+-------+-------+ | id | A | B | +----+-------+-------+ | 7 | 80410 | 80510 | | 3 | 80410 | 0 | | 6 | 80223 | 81223 | | 2 | 80223 | 81017 | | 1 | 80223 | 80505 | | 5 | 80223 | 0 | | 4 | 80110 | 80731 | | 8 | 80110 | 80630 | +----+-------+-------+ という風に並んでしまいます。 よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • 特定のデータの前後を取得したい

    以下のようなテーブルがあり、 SELECT id , regist_date FROM table_name ORDER BY regist_date DESC; ↑このSQLで並べると↓以下になるとします。 id(int型)   regist_date(datetime型) 12      2017-03-30 08:05:03 95      2017-03-29 19:05:03 72      2017-03-28 12:05:03 15      2017-03-28 12:05:03 62      2017-03-27 15:05:03 94      2017-03-26 12:05:03 やりたい事はidが72というのが分かっており、 そのデータと前後のデータを取得したいです。 ※日付の部分が完全に重複するデータが存在する場合もあります。 ※idは重複しません。 ↓このデータがとりたいです。 95      2017-03-29 19:05:03 72      2017-03-28 12:05:03 15      2017-03-28 12:05:03 SELECT * FROM table_name WHERE id = 72 ORDER BY regist_date DESC; ここから先が分からなくなってしまいどなたかわかる方いらっしゃいますか?

    • ベストアンサー
    • MySQL
  • 複数テーブルの結合

    テーブルA  a_id id a_data a_date ----------- テーブルB id b_data b_date テーブルC id c_data c_date ----------- テーブルAとテーブルBは「id」がキーで1:N(Nは0も含む) テーブルAとテーブルCは「id」がキーで1:N(Nは0も含む) このような3のテーブルで a_idを検索キーにして次のフィールドのデータを抽出したいのですが。。。 ※テーブルCのc_dateを降順で先頭の1レコードのみ ※テーブルBのidをカウントする selectの結果(イメージ) id a_data a_date count(B.id) c_date ------------------------------------- 001 AAAA 2007/02/01 20 2007/02/14 005 BBBB 2007/02/02 0 2007/02/10 006 CCCC 2007/02/02 0 2007/01/08 003 DDDD 2007/02/01 100 002 EEEE 2007/02/01 9 004 FFFF 2007/02/01 0 よろしくお願いします

  • テーブルごとのカウント

    PHP5.2+mysql 5.0.45で開発を行っております。 SQLに関する質問なのですが 以下のことが可能かどうかご教授いただきたく。 4つのテーブルがあります。 (例は適当です。項目の名称等は無視してください。) テーブルA ID Name Kana テーブルB ID NameID Pref City テーブルC ID NameID Tel Fax テーブルD ID NameID email CellPhone とします。 A.ID=1000の時各テーブルのレコード数が A:B:C:D=1:3:2:2となっています。 SQLの出力結果として A.ID A.Name A.Kana B.Count(ID) C.Count(ID) D.Count(ID) という、6項目を出力したいのですが 方法がわかりません。 試してみたのは select A.ID,A.Name,A.Kana,Count(B.ID),Count(C.ID),Count(D.ID) from A left join B on A.ID = B.NameID left join C on A.ID = C.NameID left join D on A.ID = D.NameID where A.ID = 1000 group by A.ID,A.Name,A.Kana ですが 結果、 A.ID = 1000 A.Name = Name A.Kana = Kana Count(B.ID) = 3 Count(C.ID) = 3 Count(D.ID) = 3 となってしまいます。 冷静に考えるとそうなんですが・・・ もしうまく結果を取得できる方法があればご教授いただきたく よろしくお願いいたします。

    • ベストアンサー
    • MySQL