SQLでrow_numberとoverを使って抽出

このQ&Aのポイント
  • SQLServer2012で、row_number()とover()を使って抽出を行っています。
  • 指定のテーブルに対して、IDとflgでグループ化し、flgの降順で並び替えます。
  • flgが1の場合はrankの降順、NOの昇順で並び替えます。flgが0の場合はrankの昇順、NOの昇順で並び替えます。
回答を見る
  • ベストアンサー

SQLでrow_numberとoverを使って抽出

SQLServer2012で、row_number()とover()を使って抽出を行っています。 以下の様なテーブルがあるとして ------------------------------------------- ID NO distination expensen rnak flg ------------------------------------------- A001 001 広尾 1000 1 1 A001 002 品川 1000 2 1 A002 001 大森 500 3 0 A003 001 品川 1500 2 0 A001 003 新宿 2000 4 0 A001 004 渋谷 1200 5 0 A003 002 新宿 3000 4 1 A004 003 広尾 4000 1 0 A005 002 大森 500 3 1 A003 002 品川 1000 2 1 A003 003 池袋 1300 6 0 A005 001 大森 500 3 1 これに対して row_number()とover()を使って、 (1)IDとflgでグループ化し (2)flgの降順(”1”が優先) (3)flgが”1”の場合、rankの降順、NOの昇順 (4)flgが”0”の場合、rankの昇順、NOの昇順 (5)ID毎の連番(行番号)を割り当てる これを以下に様なID毎の連番で結果を得たい。 row_number ID NO distination expensen rank flg ------------------------------------------------------- 1 A001 002 品川 1000 2 1 2 A001 001 広尾 1000 1 1 3 A001 003 新宿 2000 4 0 4 A001 004 渋谷 1200 5 0 1 A002 001 大森 500 3 0 1 A003 002 新宿 3000 4 1 2 A003 002 品川 1000 2 1 3 A003 001 品川 1500 2 0 4 A003 003 池袋 1300 6 0 1 A004 003 広尾 4000 1 0 1 A005 001 大森 500 3 1 2 A005 002 大森 500 3 1 と1回のSQLで抽出したいのですが、SQLを教えて下さい。

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

  • ベストアンサー
  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.2

ANO1です。 PARTITION BY ID,flg毎に連番がふられるの意味は これ ↓ rank* ID NO distination expensen rank flg 1 -2 A001 002 品川 1000 2 1 2 -1 A001 001 広尾 1000 1 1 1 4 A001 003 新宿 2000 4 0 2 5 A001 004 渋谷 1200 5 0 1 3 A002 001 大森 500 3 0 1 -4 A003 002 新宿 3000 4 1 2 -2 A003 002 品川 1000 2 1 1 2 A003 001 品川 1500 2 0 2 6 A003 003 池袋 1300 6 0 1 1 A004 003 広尾 4000 1 0 1 -3 A005 001 大森 500 3 1 2 -3 A005 002 大森 500 3 1 2つめのrank*がcase when flg = 1 then -1 else 1 end * rankの結果です。 これ順で、同じならNo順に連番が振られます。 で、 PARTITION BY ID,flg毎にというのは、 IDがA001でflgが、1のデータに対して、1から連番。 IDがA001でflgが、0のデータに対して、1から連番。 IDがA002でflgが、1のデータに対して、1から連番。 ・・・ という意味です。 Order by句の中にいれる項目や式は、select句と関係しないので、 以下に様なID毎の連番で結果を得たいのなら、 select句の中に別の記述をすればいいことになります。 ROW_NUMBER() OVER( PARTITION BY ID ORDER BY flg desc, case when flg = 1 then -1 else 1 end * rank, no) というような記述でいいはず。

abc999xyz
質問者

お礼

ありがとうございます。 勉強になります。

その他の回答 (1)

  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.1

select ・・・ order by ID,flg desc, ROW_NUMBER() OVER( PARTITION BY ID,flg ORDER BY case when flg = 1 then -1 else 1 end * rank,no) で出ると思いますが。 PARTITION BY ID,flg・・・ID,flgごとに連番を取得する。 ORDER BY flg = 1のとき、-rankの昇順=rankの降順 他 rankの昇順 で、rankが同じ値ならnoの昇順 で、ID,flgごとに1から連番を振られるのこれをorder by句で使えばいい。

abc999xyz
質問者

お礼

回答ありがとうございます。 スキル不足ですみません。 >ORDER BY case when flg = 1 then -1 else 1 end * rank,no) の意味が分かりません。 と 「PARTITION BY ID,flg・・・ID,flgごとに連番を取得する。」 以降の内容がわかりません。 もう少し説明いただけないでしょうか。

関連するQ&A

  • SQLの書き方について

    以下の様なデータある場合 【Aテーブル】 ------------- NO,ITEM, KOSU ------------- 1 ,001 , 1 2 ,002 , 3 3 ,003 , 1 【Bテーブル】 ------------------- NO,NENDO,CODE,BIKO ------------------- 1,2006 , 1 , 1111 1,2007 , 0 , 1111 1,2007 , 2 , 1111 2,2007 , 0 , 2222 3,2007 , 0 , 3333 3,2007 , 1 , 3333 ------------------------------ NO,NENDO,CODE,BIKO,ITEM,KOSU ------------------------------ 1,2007 , 0 , 1111,001 , 1 2,2007 , 0 , 2222,002 , 3 3,2007 , 0 , 3333,003 , 1 と出力。(キーはNo) NO毎のかつ年度の降順、コードの昇順で最新の1件を 取得するにはどのようなSQLを作成したらよいのでしょうか?

  • Oracle[10g]のSQL文について。(新No.3)

    なんども、恐縮です。 Oracle[10g]のSQL文についての質問です。(新No.3) 実は、JOINが多くてどこに[ROW_NUMBER]を入れれば良いのか解りません。 [A]テーブルに [CODE](KEY) [CODE2] のフィールドがあります。 A-1 B-1 A-2 B-2 A-3 B-3 [A2]テーブルに [CODEB](KEY) [CODE2] のフィールドがあります。 AA-1 B-1 AA-2 B-2 AA-3 B-3 [B]テーブルに [CODE3](KEY) [NAME-B] のフィールドがあります。 B-1 NAME-B-1 B-2 NAME-B-2 [C1]テーブルに [NO](KEY) [LINE](KEY) [CODE] [CODEB]のフィールドがあります。 X 1 A-1 AA-2 X 2 A-3 AA-1 Y 1 A-2 AA-3 [C2]テーブルに [NO](KEY) [LINE](KEY) [LINE2](KEY) [BIKO] のフィールドがあります。 X 1 1 BIKO-1 X 1 2 BIKO-2 結果が [NO/LINE/CODE/CODEB/NM1/NM2/BIKO] X 1 A-1 AA-2 NAME-B-1 NAME-B-2 BIKO-1 X 2 A-3 AA-1 (null) NAME-B-1 (null) と、なる様にしたいのです。 要するに、のBIKOは、[C2.LINE2]の一番最小の物を取得したいのです。 SELECT C1.NO, C1.LINE, C1.CODE, C1.CODEB, B.NAMEB AS NM1, B_1.NAMEB AS NM2, C2.LINE2, C2.BIKO FROM ((((C1 LEFT JOIN A ON C1.CODE = A.CODE) LEFT JOIN B ON A.CODE2 = B.CODE3) LEFT JOIN A2 ON C1.CODEB = A2.CODEB) LEFT JOIN B B_1 ON A2.CODE2 = B_1.CODE3) LEFT JOIN C2 ON (C1.LINE = C2.LINE) AND (C1.NO = C2.NO) WHERE (((C1.NO)='X')) ORDER BY C1.NO, C1.LINE, C2.LINE2; と、考えたのですが、結果が X 1 A-1 AA-2 NAME-B-1 NAME-B-2 1 BIKO-1 X 1 A-1 AA-2 NAME-B-1 NAME-B-2 2 BIKO-2 X 2 A-3 AA-1 (null) NAME-B-1(null)(null) と、出てしまいます。 どうすれば良いのでしょうか ? 宜しくお願い致します。

  • 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
  • 勤務地が変わることが多い場合の部屋探し

    現在の勤務地の最寄り駅が、JR:大森 京急:大森海岸 です。 同棲生活(1年以内に結婚予定)を始めるために近辺で賃貸マンションを探そうと考えているのですが、職業柄で勤務地が短ければ数ヶ月~長くても2,3年程度でコロコロ変わる可能性が高いです。 もっとも、勤務地はだいたい品川~横浜あたり、もしくは山手線沿線の西寄り(新宿、池袋、恵比寿など)です。ごく稀に東陽町なんて話もありますが。 そういう条件で考えると、やはり京浜東北/根岸線か京急沿線、もしくは簡単にどちらかに乗り換えられる沿線がいいかなぁ・・・とは考えています。 <希望など> 1.私も同棲相手も車の免許が無い(また、今のところ取得の予定も無い)ため、電車の便は良いところがいいなぁとは考えています。 2.勤務地になり得る各地(品川~横浜、新宿・池袋・恵比寿あたり)まで、大体1時間以内で行けるといいな、と考えています。 3.個人的には横浜への憧れがあるので(笑)、その近辺でいいところがないかなぁとも思っているのですが・・・。 このような条件でおすすめの場所はあるでしょうか? 不躾な質問で申し訳ありません。 どうか、アドバイスお願いいたします。

  • エクセル【昇順・降順で並べ替え】について

    エクセル【昇順・降順で並べ替え】について 下記のようにエクセル表に入力したものを23日→4日に並べ替えをしたいのです。 昇順をしてみたら、番号が狂ってしまいます。 日付け順に狂いなく並べ替えができる方法を教えてください。 どうぞ宜しくお願いします。 日付け 番号 ランク 1月4日 101 A 1月5日 102 C 1月9日 103 B 1月9日 104 A 1月19日 105 C 1月23日 106 A 1月23日 107 C 1月23日 108 C

  • エクセルマクロについて教えてください

    エクセルで A~F列に 「 組 No. 枠  記号 コードA コードB」と並べています。 2行目以降に、「記号」を除き数値が入ります。 ※ お手数をおかけしますが画像を確認願います。ご覧頂いたほうがわかりやすいと思いますので。 これを、 (1) 組・No.・枠 固定 (記号・コードA・コードBが並び変わっても不動) (2) コードA 降順 (3) コードB 昇順 (4) 2~9行目の コードAを昇順で枠Aに指定された順に 上記のように並べ替えをしたい場合、どのようなマクロを作成したらよろしいでしょうか?  

  • C言語について

    ソートを使い入力した数値を並び替える。昇順、降順を選べるようにする。 順位を付けるた。ただし、複数同位があった場合にはその個数分順位が変更する。 このような問題なのですが 入力個数の部分までは自力でできたのですが、ソートを習っていないのでこの後がよく分かりません。 下のような実行結果になるようだれかわかる人お願いします。 # include <stdio.h> int main(void) { int a[100],kai=0,sentaku; printf("整数を入力(CTRL+dで終了) >> "); while(1){ if(scanf("%d",&a{kai}) == EOF )break; kai=kai+1; printf("整数を入力(CTRL+dで終了) >> "); } printf("入力個数%d回\n",kai); return 0; } 実行結果 数値>>1 数値>>3 数値>>-1 数値>>-3 数値>>10 数値>>3 数値>> 入力回数:4回 1:昇順、2:降順>>1 NO.1:-3 NO.2:1 NO.3:3 NO.3:3 NO.5:10

  • Access連番(VBA)についてアドバイスください。

     環境OSーXP ACCESS2003 ID(オートナンバー)  社名  連番 1           A社 2           A社 3           A社 4           B社 5           B社 6           C社 7           C社 求める結果(VBAーCMDボタンでイベント) ID(オートナンバー)  社名  連番 1           A社   1 2           A社   1 3           A社   1 4           B社   2 5           B社   2 6           C社   3 7           C社   3 Accessculbなどで検索しましたが、グループごとに連番振り方の教程ありますが、↑のような教程まだ見つからないです。 VBA勉強して、まだ浅いので、ぜひ教えてください。 考え方を教えてください。

  • フォーム内のテキストボックスに複数レコードを表示

    いつも大変お世話なっております。Accessを始めて3週間の初心者です。 今、社員の在籍中の職級推移を残すための社員明細フォームを作成しています。 社員数数百名。 フォーム名:社員明細 テーブル名:TBL_職級期間一覧 テーブルには 以下のようなレコードが並んでいます。 IDはオートナンバー型を振っています。 年度が替わって、職級が変化すればレコードが追加されます。 (ID 586のように001234 さんのレコードが追加)  ID  社員No    開始     終了    職級名  1  001234  2004/04/01 2008/03/31   S3  2  001234  2008/04/01 2012/03/31   S2  3  001234  2012/04/01 2015/03/31   S1  4  005678  1998/04/01 2003/03/31   T6  5  005678  2003/04/01 2005/03/31   T5  6  005678  2005/04/01 2013/03/31   T4  7  005678  2013/04/01 2016/03/31   T3  ・  ・  ・ 586  001234  2015/04/01 2016/03/31   K5 これらを添付写真のようにフォームに表示させる方法がわかりません。 IDを振ったのは社員Noで絞り込み、昇順・降順で表示させる順番を 推移の新しい順、古い順に可変させられるのでは・・?と思ったので IDフィールドを付けました。 いろいろ検索し=DLOOKUPを使ったりと試してみましたが、よくわかり ませんでした。 何卒お力添えをお願い致します。

  • 複数行に対しての更新処理方法

    失礼いたします。 現在、ランキングの表示順序を変更する画面を作成しようとしています。 Table:RANK ID  NAME  NO ----------------- 1   AAAA 5 2 BBBB 2 3 CCCC 1 4 DDDD 6 5 EEEE 6 FFFF TableにはIDをキーにして、名称(NAME)と表示順番(NO)があり、 表示画面上では表示順番(NO)が入力フォームになっています。 mysql_fetch_rowでSQLでとって来た値を配列$rkにとり、 上記のTable内容のNAMEとNOをリスト表示するまではでき たのですが、次に表示順番(NO)を更新して保存する方法が わからず困っています。 1レコードに対してなら UPDATE RANK SET NO=*** WHERE ID=** なんかでできるのではと思うのですが、 一度保存ボタンを押したら各IDに対しそのNOの値が保存するように したいので、各IDに対しての保存する複数行のUPDATEはどうしたら いいでしょうか。 わかりづらい点あると思いますがコメントお願いします。

    • 締切済み
    • PHP