MySQLでシーケンス番号の前後数を知る方法

このQ&Aのポイント
  • MySQLでGroup内のシーケンス番号の前後数を知る方法について説明します。
  • ユーザーテーブルにおいて、特定のグループとシーケンス番号を持つユーザーの前後のシーケンス番号を取得する方法を解説します。
  • サブクエリを使わずに、シーケンス番号の前後数を取得する方法について考えます。
回答を見る
  • ベストアンサー

MySQLでシーケンス番号の前後数を知りたい

user_table ---------------------------- id | group_id | sequence| name | ---------------------------- 1 | 1 | 1 | emi | ---------------------------- 2 | 1 | 2 | shun | ---------------------------- 3 | 2 | 1 | yumi | ---------------------------- 4 | 1 | 5 | jo | … group_idごとにシーケンス番号(グループ内のユニーク番号)を振っています。 shun(group_id=1,sequence=2)のページでシーケンス番号の前後を取りたいのですがどうすればいいでしょうか? すでに辞めたユーザもいるためシーケンス番号は必ず連続しているとは限らず、抜けている場合もあります。 例として、shun(group_id=1,sequence=2)の前後を取る場合はemiとjoのシーケンス番号を取得したいのです。 下記で出来ましたがサブクエリなしでもできそうなのとあまりきれいでないのでご教示お願いいたします。 select (select min(sequence) from t_files where album_id=1 and sequence>2) next,( select min(sequence) prev from t_files where album_id=1 and sequence<2) prev;

  • MySQL
  • 回答数3
  • ありがとう数4

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

  • ベストアンサー
  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.3

条件が異なるから普通に、二回 SELECT * FROM user_table WHERE group_id = 1 AND sequence > 2 ORDER BY sequence LIMIT 1; SELECT * FROM user_table WHERE group_id = 1 AND sequence < 2 ORDER BY sequence DESC LIMIT 1; どーしても一回で済ませたいなら、 SELECT  MAX(CASE sequence < 2 THEN sequence ELSE NULL END) AS prev  MIN(CASE sequence > 2 THEN sequence ELSE NULL END) AS next FROM user_table WHERE group_id = 1; 又は SELECT  * FROM user_table WHERE group_id = 1  AND sequence >= (   SELECT sequence FORM user_table WHERE group_id = 1 AND sequence < 2    ORDER BY sequence DESC LIMIT 1  )  AND sequence <> 2 LIMIT 2;

szkshi
質問者

お礼

ありがとうございます。 ご教示いただいたものが少し間違っていたため下記のように修正し、実現しました。 SELECT MAX(CASE when sequence < 2 THEN sequence ELSE NULL END) AS prev, MIN(CASE when sequence > 2 THEN sequence ELSE NULL END) AS next FROM user_table WHERE group_id=1; 本当にありがとうございました!

その他の回答 (2)

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

例示より長くなってしまいちょっと微妙なんですが ちゃんとやるならこんな感じになりそうな気がします。 ちなみにSQLは効率を考えて2つにわけてあります select @rank:=( select count(*) from user_table as u2 where u1.group_id=u2.group_id and u1.id>u2.id ) as rank from user_table as u1 where group_id=1 and sequence=2 ; select ( select count(*) from user_table as u2 where u1.group_id=u2.group_id and u1.id>u2.id ) as rank ,`u1`.* from user_table as u1 where group_id=1 having rank between @rank -1 and @rank +1

szkshi
質問者

お礼

ありがとうございます。 ご教示いただいたものより、私がすでに書いたものほうが効率的な気がします。。 select (select min(sequence) from user_table where group_id=1 and sequence>2) next,( select min(sequence) prev from user_table where group_id=1 and sequence<2) prev;

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.1

例として提示されているのが「user_table」で、実際につくられたSQLのテーブルが「t_files 」、しかも「user_table」にはない「album_id」が出てきています。 「ページ」という言葉も出てますが、これがどういう意味なのかも分かりません。 ちょっと答えようがないです。

szkshi
質問者

お礼

ご指摘いただきありがとうございます。 間違えておりました。 正しくは下記になります。 select (select min(sequence) from user_table where group_id=1 and sequence>2) next,( select min(sequence) prev from user_table where group_id=1 and sequence<2) prev;

szkshi
質問者

補足

お礼の文も間違えてました。。。 select (select min(sequence) from user_table where group_id=1 and sequence>2) next,( select max(sequence) prev from user_table where group_id=1 and sequence<2) prev;

関連するQ&A

  • ★Mysql 同じ条件で●●から同じ数だけ抽出!

    SELECT * FROM `table` WHERE `abc`=1 and `def`=3 and GROUP BY ●● order by rand(); この条件なら、●●が1件ずつ計30件が抽出されます。 が、 私がやりたいのは、●●から3件ずつで、 3×30=90件 抽出したいです。 一文でできるのでしょうか? 初心者ですみません。 よろしくお願いします。

  • mysql

    $sql='SELECT id,kaisyamei, max(day),namae FROM message WHERE memberid=? GROUP BY id LIMIT '.$limit.' OFFSET '.$offset; どこか違いますか?

    • ベストアンサー
    • MySQL
  • SQL文について困っています

    ID(NUMBER型)と NUM(NUMBER型)と nenngetu (date型)を持ったテーブルAAAから、 ID=1000 のなかで日時が一番古い処理NOをselectするSQL文を書きましたが上手く実行されません。 select NUM from AAA where nenngetu = (select min(nenngetu) from AAA) and ID=1000; ID=1000の条件をはぶき、 select NUM from AAA where nenngetu = (select min(nenngetu) from AAA); でしたら、実行できました。 oracleで実行しようとしています。 どなたか、書き方を教えてください。

  • 条件をつけてレコードを取得したい

    以下のようなA,Bテーブルから条件を指定してレコードを取得したい 【Aテーブル】 ID Bテーブル番号 0001      null 0002      null 0003      null 【Bテーブル】 シーケンス番号   ID    登録日 処理済みフラグ       0010  0001 2014/01/01        0       0011  0001 2014/01/02        1       0012  0001 2014/01/03        0 <結果> 【Aテーブル】 ID Bテーブル番号 0001     0001 0002     null 0003     null 条件としては以下の条件です。 (1)Aテーブルは全レコード出力する (2)BテーブルのAテーブルシーケンス番号が複数存在する場合、登録日が一番古いレコードを抽出する (3)Bテーブルの処理済みフラグが0のレコード以外はnullとする。 自分で抽出条件を作成したのですが、Aテーブルの0001分しか上手く抽出出来ませんでした。 SELECT * FROM Aテーブル AT (SELECT シーケンス番号, MIN(登録日) AS 登録日 FROM Bテーブル GROUP BY AテーブルID) BT1, (SELECT * FROM Bテーブル) BT2 WHERE AT.ID = BT1.ID AND BT1.登録日 = BT2.登録日 AND BT1.ID = BT2.ID AND BT2.処理済みフラグ = '0' 一度上の命令文でテーブルを作って元のテーブルとマッチングさせるしかないのでしょうか?出来れば一発で抜き出したいです。 ご教授宜しくお願いします。

  • MySQLでサブクエリーが使えないため困っています

    MySQL3.23.58にて以下のSQLを実行したいのですが、 サブクエリーが利用できないため困っています。 やりたいことは、 1.memberテーブルにemailが重複したデータがあるため、 ユニークなemailを取得したい。 2.取得したemailを元にmemberテーブルを参照し、 シーケンシャルでユニークなidを取得したい。 3.その取得したidを元にflagが立っているものを取得したい。 以上になります。 実際に行いたいSQL文は以下になります。 select count(*) from member where id in ( select max(id) from member where email in ( select distinct email from M_MEMBER where email != '' and email not like '%@docomo.ne.jp' and email not like '%ezweb.ne.jp' and email not like '%ido.ne.jp' and email not like '%vodafone.ne.jp' and email not like '%@jp-%' ) ) and flag = 1; どうかよろしくお願いいたします。

  • SQL シーケンスについて

    Orcle8iを使用しています。 INSERT INTO SELECT で別のテーブルのデータを追加したいのですが、そのうち1つフィールドには、シーケンスオブジェクトで取得した値を入れたいと思っていますが、INSERT文が作れません・・・。 例えば ----------------------------- INSERT INTO TABLE1(FIELD1,FIELD2,FIELD3)   SELECT --SELECT SEQ.NEXTVAL FROM DUAL??--     FIELD1_2,     FIELD1_3 FROM TABLE2 WHERE FILED1_2='X'; ----------------------------- という場合、TABLE1のFIELD1に連番を入れたいのですが 書き方が分かりません。 http://www.okweb.ne.jp/kotaeru.php3?q=347146 上記URLの質問に、シーケンスのSELECT文を副問い合わせにして・・・という回答があったのですが、それもよく理解できませんでした・・・(T_T) シーケンスのSELECT文をどう埋め込めば良いのでしょうか? どなかた教えていただけませんか? よろしくお願いします。

  • MySQL SELECT結果をSET

    質問は二つあります。 (1)二つのコードをひとつにしたいのですが、どうもうまくいきません SELECT id, (price * 10) FROM table WHERE id = 1; SET @sum = @sum + (SELECT ( SELECT id, (price * 10) FROM table WHERE id = 1); (2)コードの簡略化 SELECT id, (price * 10) FROM table WHERE id = 1 OR id = 3 OR id = 8; の、WHERE id = 1 OR id = 3 OR id = 8; の部分です。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • SQL文で困っています。

    ID(NUMBER型)と NUM(NUMBER型)と nenngetu (date型)を持ったテーブルAAAから、 ID=1000 のなかで日時が一番古い処理NOをselectするSQL文を書きましたが上手く実行されません。 select NUM from AAA where nenngetu = (select min(年月) from D_KR_SAP_IFRIREKIKANRI) and ID=1000; ID=1000の条件をはぶき、 select NUM from AAA where nenngetu = (select min(年月) from D_KR_SAP_IFRIREKIKANRI); でしたら、実行できました。 oracleで実行しようとしています。 どなたか、書き方を教えてください。

  • Mysql サブクエリの使い方

    table_A ---+------ id | count ---+------ 1 | 5 ---+------ 2 | 6 ---+------ 3 | 7 ---+------ table_B ---+----- id | sub_count ---+----- 1 | 2 ---+------ 2 | 2 ---+------ 3 | 5 ---+------ 1 | 3 ---+------ 2 | 4 ---+------ このようなテーブルで table_Aのcountと、table_Bのidでまとめたsub_countの合計が 一致しないidだけを抽出するために、 SELECT table_A.id FROM (SELECT sum(table_B.sub_count) FROM table_B GROUP BY table_B.id) AS B, table_A, table_B WHERE table_A.id = table_B.id AND table_A.count != sum(table_B.sub_cout) と書いてみましたが、うまくいきません。 ERROR 1111 (HY000): Invalid use of group function 何が悪いのでしょうか? mysqlも投稿も初心者です。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • シーケンスのリストを取得したい。

    いつもお世話になっております。 インターネットサーバー上のPHPから postgreSQLのデータベース内の テーブル名とシーケンス名のリストを SELECTを使ったSQL文にて取得したいのです。 テーブルリストは、 select * from pg_tables where not tablename like 'pg%' order by tablename; で取得できましたが、 シーケンス名のやり方がわかりません。 phppgadminでシーケンスの表が表示できるので、 phpでも出来ると思うのですがわかりません。 お知恵をおかしください。 hiroko