• ベストアンサー
  • すぐに回答を!

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;

共感・応援の気持ちを伝えよう!

  • 回答数3
  • 閲覧数375
  • ありがとう数4

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

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

条件が異なるから普通に、二回 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;

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ありがとうございます。 ご教示いただいたものが少し間違っていたため下記のように修正し、実現しました。 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; 本当にありがとうございました!

関連するQ&A

  • Oracleのシーケンスありのテーブル作成について

    Oracleのテーブルを作るのに、ある列を自動で「全体の通し番号」みたいなユニーク(一意)な番号を振りたいく、 シーケンス(sequence)を作成しテーブルを作ろうとしているのですがうまくいきません。 どこがわるいのでしょうか。 create sequence "yamaaf_seq"; CREATE TABLE TBL_AFFILIATE_SESS( UNIQ_ID NUMBER(11,0) DEFAULT nextval('yamaaf_seq') NOT NULL, ORG_CODE VARCHAR2(64) NOT NULL, primary key("UNIQ_ID"));

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

    以下のような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' 一度上の命令文でテーブルを作って元のテーブルとマッチングさせるしかないのでしょうか?出来れば一発で抜き出したいです。 ご教授宜しくお願いします。

  • Accessで最小値と最大値を一度で取得する方法

    OS:WinXP Access:2000 下記の状態にしたいのですが よいSQL文が思いつきません。 MINのみのデータを抽出する方法は分かるのですが select ID,Name,Min(Date) from tblA group by ID,Name,Date MAX(Date)も出力しようとすると、Dateが最小のNameの出力方法が分かりません。 テーブル(tblA) ID|Name|Date --------------- 01|C |8/10 01|A |8/11 01|B |8/12 ↓ クエリ実行後 ID|MIN(Name)|MIN(Date)|MAX(Date) ----------------------------------- 01|C |8/10 |8/12 よろしくお願いいたします。

その他の回答 (2)

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

例示より長くなってしまいちょっと微妙なんですが ちゃんとやるならこんな感じになりそうな気がします。 ちなみに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

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ありがとうございます。 ご教示いただいたものより、私がすでに書いたものほうが効率的な気がします。。 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;

  • 回答No.1

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

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ご指摘いただきありがとうございます。 間違えておりました。 正しくは下記になります。 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;

質問者からの補足

お礼の文も間違えてました。。。 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

  • グループ化したいのですが

    テーブルAに以下のような項目があります。 [ID][SEI][MEI] やりたい事は、 ・[ID]ごとにグループ化して1行にまとめたい。 ・[SEI]と[MEI]をつなげて1つの項目として表示させたい。 これを実現させるには、どういうSQLを書けば良いでしょうか? 私が試したのは、以下のSQL文です。 SELECT ID,MIN(SEI) + MIN(MEI) AS NAME FROM TABLEA GROUP BY ID でも、これだと同じIDが複数存在すると[SEI][MEI]が別人のものがくっついてしまいます。当然ですが。 グループ化する前に[SEI][MEI]を連結させる処理が必要なのだろうと思うのですが、それをどうすれば良いのかが分かりません...。 どうかよろしくお願いします。m(_ _)m

  • 副問合せを使わないでグループごとの最新日付を取得

    MySQL4.0.2x を使用して、検索プログラムを実装させようとしていますが、 副問合せに慣れてしまってどうSQL文を書いてよいか考えあぐねています。 何かよいやり方がありましたらご教授ください。 やろうとしていることは、以下の発行履歴テーブルを購入IDでグループ化し、そのグループ内で発行日が最新のレコードを、全カラム分引っ張ってくる。 (結果は購入IDが一意になっている) そしてそのテンポラリーテーブルを作成することです。(後で別テーブル群と購入IDでJOINさせるため) どうもサンプルテーブルの空白が崩れてしまって見づらくて申し訳ないですが、宜しくお願いします。 ■ユニーク:参照番号 +----------+--------+------------+---------------+---------------------+---------------+-------- | 購入ID | 連番 | 商品コード | 参照番号 | 発行日 | IP   | ・・・ (以降略) +----------+--------+------------+---------------+---------------------+---------------+-------- | 0001 | 1 | pen_00580 | 000000001_001 | 2008-01-01 00:11:01 | 123.45.678.90 | ・・・ | 0002 | 1 | rot_00187 | 000000002_001 | 2008-01-03 00:13:49 | 111.22.333.44 | ・・・ | 0002 | 2 | rot_00187 | 000000002_002 | 2008-01-03 00:14:25 | 111.22.333.44 | ・・・ | 0003 | 1 | ter_09523 | 000000003_001 | 2007-12-25 00:19:40 | 555.66.777.88 | ・・・ | 0004 | 1 | rot_00187 | 000000004_001 | 2007-12-28 00:20:02 | 999.88.777.66 | ・・・ | 0005 | 1 | min_00210 | 000000005_001 | 2007-12-26 00:20:10 | 543.21.098.76 | ・・・ | 0005 | 2 | min_00210 | 000000005_002 | 2007-12-30 00:30:55 | 543.21.098.76 | ・・・ | 0005 | 3 | min_00210 | 000000005_003 | 2008-01-03 00:36:30 | 543.21.098.76 | ・・・ | 0006 | 1 | rot_00187 | 000000006_001 | 2008-01-10 00:45:24 | 123.45.678.90 | ・・・ +----------+--------+------------+---------------+---------------------+---------------+-------- ちなみに自分が作成したもの (1)第1回一時テーブル CREATE TEMPORARY TABLE 一時テーブル1 SELECT 購入ID, max(参照番号) 参照番号, max(発行日) 発行日 FROM 発行履歴 GROUP BY 購入ID (2)第二回一時テーブル CREATE TEMPORARY TABLE 一時テーブル2 SELECT A.* FROM 発行履歴 A RIGHT JOIN (一時テーブル1) B ON A.参照番号=B.参照番号

    • ベストアンサー
    • MySQL
  • 条件をつけて日付の古い行を抜き出したい

    SQLserver2005を使っています。 下記のようなテーブルがあります。 ID 処理番号  日付   Data AA  1    2008/1/1  10 AA  1    2008/1/2  11 AA  1    2008/1/3  12 AA  2    2008/1/4  13 AB  3    2008/1/5  14 AB  3    2008/1/6  15 AB  4    2008/1/7  16 この時に「IDと処理番号が一致した場合、日付の一番古い行を抜き出す」 という条件でデータの抽出をすることは可能でしょうか 結果は下記のようになります。 ID 処理番号  日付   Data AA  1    2008/1/1  10 AA  2    2008/1/4  13 AB  3    2008/1/5  14 AB  4    2008/1/7  16 下のような命令文を作ったのですが、 「Data列」が抜き出せません。 select ID,処理番号,min(日付) from テーブルA Group by ID,処理番号 一度上の命令文でテーブルを作って元のテーブルとマッチングさせるしかないのでしょうか?出来れば一発で抜き出したいです。 ご教授宜しくお願いします。

  • MYSQLで結合の仕方教えてください

    db_test.sales db_test.prodct db_test.dailyreport という3つのテーブルがあります 以下のようなSQL文に集計したデータも結合したいのですが Join結合の使い方が分かりません SELECT PD.productid as '製品番号', SR.cono as '客先側注文番号', str_to_date(SR.tehaiday,'%Y%m%d') as '手配日', str_to_date(SR.noukiday,'%Y%m%d') as '納入予定日', PD.hinmei as '製品名称', PD.daisu as '台数', PD.costsales as '原価', FROM db_test.sales SR, db_test.prodct PD, WHERE SR.productid = PD.productid AND SR.noukiday Like '201609%' ORDER BY PD.noukiday という2テーブルから引っ張ってきているMYSQL文があります。 先月の納期ぶんを抽出した生産の一覧です。 そこのテーブル右端に更に追加しまして 日報データから個々の作業に掛かった時間を製品番号毎に 集計したものを追加したいです。select文の末尾に (SELECT DR.productid as '製品番号', total(DR.worktime) AS '作業時間' FROM db_test.dailyreport DR GROUP BY DR.productid) を入れたいです。 FROM句に db_test.prodct inner join db_test.dailyreport on PD.productid = DR.productid と追加書いてみたのですがこれでは駄目でしょうか。 正しくはどう書けばよいのでしょうか?

    • ベストアンサー
    • MySQL
  • ループ処理について

    こんにちわ。ループ処理についての質問があります。 現在、ページ内での「前へ」というボタン設定をしています。その際、コード番号を元にして値をもってきていますが、1つ前のコードがない場合、DB内の更に前のコードを自動的に調べて持って来たいのです。 コードのtypeがTEXTで、値が03-00122のように入っています。 1つ前だけならこれでできるのですが、DB内の更に前のコードを自動的に調べて作成する方法が多分ループ処理を使って、$rs==1の時(データが存在する時)にぬければいいと思うのですが・・ どなたかご教授の方、お願いします。 php4.2です。 //年度取得 $N=substr($Number,0,3); //「前へ」 $i=1; $H=substr($Number,-5)-$i++; $I='000'.$H; $J=substr($Number,0,2); $BackNumber=$J.'-'.substr($I,-5); //$BackNumberがあるか確認 $sl="select * from student where number='$BackNumber'"; $rs=pg_exec($con,$sl); $row=pg_numrows($rs); //numberのmin値を得る $min = "select min(number) from base where number like '$N%'"; $resource_id = pg_exec($min); $remin = pg_result($resource_id, 0, "min"); // 1ページ目じゃなかったら「前へ」をつける if ($remin != $Number){ $prev = $page - 1; print("<A HREF=\"base.php?Number=$BackNumber\"><I>前へ</I></A>\n"); print(" \n"); }

    • ベストアンサー
    • PHP
  • group by句

    色々と試行錯誤してやっていますが、なかなか自分の 思うような結果が得られないためご質問させて下さい。 テーブルが全部で3つあります。 テーブルA id name 1 巨人 2   西武 テーブルB id name 1 小笠原 2 ラミレス 3 中島 4  片岡 テーブルC id テーブルAID テーブルBID 背番号 1 1 1 30 2 1 2 10 3 2 3 3 4 2 4 8 テーブルを結合し、テーブルCにある 背番号をテーブルAid,テーブルBidを元に sumしたいのですがうまくいきません。 以下がそのSQLになります。 (1)サブクエリーを使ったSQL この場合値が重複されて表示されてしまいます。 select a.name,b.name,c.name, (select sum(背番号) from tableC c where c.テーブルAId = a.id group by c.テーブルAid ), (select sum(背番号) from tableC c where c.テーブルBid = bid group by c.テーブルBid ) from tableC c inner join tableA a on a.id = c.テーブルAid inner join tableB b on b.id = c.テーブルBid (2) select a.name,b.name,c.name, (select sum(背番号) from tableC c where c.テーブルAId = a.id ), (select sum(背番号) from tableC c where c.テーブルBid = bid ) from tableC c inner join tableA a on a.id = c.テーブルAid inner join tableB b on b.id = c.テーブルBid group by c.テーブルAid 重複はされないのですが、group byが一つのみなので ちゃんとした出力がされません。    他にやり方があるのかもしれませんが、お分かりになる方が    いらっしゃいましたら、ご教授お願い致します。

  • グループ化したいのですが

    テーブルAに以下のような項目があります。 [MAIL_ID][SEND_DATE][USER_ID] テーブルBに以下のような項目があります。 [USER_ID][SEI][MEI] やりたい事は、 ・テーブルAとBを[USER_ID]をキーにして結合させたい。 ・テーブルAの[MAIL_ID]ごとにグループ化して1行にまとめたい。 ・テーブルBの[SEI]と[MEI]をつなげて1つの項目として表示させたい。 これを実現させるには、どういうSQLを書けば良いでしょうか? 私が試したのは、以下のSQL文です。 SELECT A.MAIL_ID, MIN(A.SEND_DATE) AS SEND_DATE,MIN( A.USER_ID) AS USER_ID,MIN(B.SEI) + MIN(B.MEI) AS ATESAKI FROM TABLEA A INNER JOIN TABLEB B ON A.USER_ID = B.USER_ID WHERE A.SEND_ID = '900001' GROUP BY A.MAIL_ID でも、これだと同じMAIL_IDが複数存在すると[SEI][MEI]が別人のものがくっついてしまいます。当然ですが。 グループ化する前に[SEI][MEI]を連結させる処理が必要なのだろうと思うのですが、それをどうすれば良いのかが分かりません...。 どうかよろしくお願いします。m(_ _)m

  • 複数テーブルの集計その2

    お世話になります。 先日テーブルの集計について教えていただき、下記集計結果を取得することができたのですが、 新たに自由形50~平泳ぎ50までの合計を追加したいのです。(一人で4種目参加する場合は4と数える) テーブル1 AreaID   AreaName --------------------- 1 北海道 2 東北 テーブル3 ID AreaID   Name  Item1   Item2  Item3 Item4 --------------------------------------------------------- 1   2    鈴木    2    1    4     3 2   1    田中    1    2    null   null 3   2    伊藤    3    null   2    4  「集計結果」       参加人数 自由形50 自由形100 背泳ぎ50 平泳ぎ50  追加部分 --------------------------------------------------------------- 北海道     1     1       1      0      0       2 東北      2     1       2      2      2       7   $sql="select AreaName, count(distinct ID) 参加人数, count(case when Item=1 then 1 else null end) as 自由形50, ・・・略 from t1 as x left join (select ID,AreaID,1 as Item from t3 where Item1=1 or Item2=1 or Item3=1 or Item4=1 union all select ID,AreaID,2 as Item from t3 where Item1=2 or Item2=2 or Item3=2 or Item4=2 ) as y on x.AreaID=y.AreaID group by AreaName order by x.AreaID というようにおしえていただきました。 null以外を取得するSQLをカウントとselectに追加すればいいのかと思い試したのですが期待した値を取得できません。 count(case when Item=AAA then 1 else null end) as abc,と union all select ID,AreaID,AAA as Item from テーブル3 where ItemID1<>'' or ItemID2<>'' or ItemID3<>'' or ItemID4<>'' or (ItemID1<>'' and ItemID2<>'') ・・・ バージョンはMySQL4.1.18です。 よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • SQL文でデータを抽出できない。

    現行のSQL文でACCESSからデータを抽出してきていたのですが、それでは問題が起きてしまったので、以下の内容にSQLを変更したいのですが、思うようにできません。 詳しい方がいましたらご教授願います。 お手数ですが、困っているのでよろしくお願いいたします。 *現行のSQL* 日付が最も若いものでかつ、IDとSUBJECTに重複のない データを抽出する。 "SELECT .sID,B.subject,B.D_time FROM (SELECT sID,Min(D_time) AS mtime ,subject FROM Reg1Data GROUP BY sID,subject) A INNER JOIN Reg1Data B ON A.sID=B.sID AND A.mtime=B.D_time GROUP BY B.sID,B.subject,B.D_time ORDER BY B.sID,B.subject;" *変更したいSQL* ある範囲の日付の中で(日付は、入力画面から抽出)日付が最も若いものでかつ、IDとSUBJECTに重複のないデータを抽出する。 "SELECT .sID,B.subject,B.D_time FROM (SELECT sID,Min(D_time) AS mtime ,subject FROM Reg1Data WHERE D_time <= & w_jyukobistart GROUP BY sID,subject) A INNER JOIN Reg1Data B ON A.sID=B.sID AND A.mtime=B.D_time GROUP BY B.sID,B.subject,B.D_time ORDER BY B.sID,B.subject;" 以上を実行すると、 [Microsoft][ODBC Microsoft Access Driver] クエリ式 'D_time <= & w_jyukobistart' の 構文エラー : 演算子がありません。 というエラーが出ます。 ちなみにw_jyukobistart はWEBの画面上に入力された抽出したいデータ範囲(from)です。 この変数の使い方に問題があるのか、それともSQL文自体に無理があるのか、最も良い方法をお尻の技術者の方、お答えいただけるとうれしいです。

  • 副問合せの書き方について

    実行したい内容は、『同一ナンバー内で1番IDが低いコードNOが2のタイトルを出す』といった内容になります。 以下のように書いて実行したところ、『EXISTSを使わないサブクエリでは、サブクエリの選択リストには、式を1つだけしか使えません。と表示されました。』自身のSQL文に問題があるかもしれませんが、現状は下記のSQL文となっています。 "SELECT id, code, num, title FROM contents WHERE code=2 AND id IN (SELECT MIN(id), num FROM contents GROUP BY num)" 副問合せで、同一ナンバーで1番IDが低いIDを取得し、取得したIDをもとに タイトルを出そうとしました。 どなたか御指導御願い願えませんでしょうか。 宜しく御願いいたします。