質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Oracle Database 11g

Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

5回答

2272閲覧

SQLの絞込みの条件について

haru07

総合スコア13

Oracle Database 11g

Oracle DatabaseはRDBMSの商品です。具体的な発売商品として知られているのが、 Oracle9i、Oracle10g、Oracle 11gとOracle 12cです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

3グッド

2クリップ

投稿2016/02/11 06:01

編集2016/02/11 06:25

SQLで複数のテーブルをJOINさせた時の表示の仕方で悩んでいます。
JOINの結果で以下のような1の結果が返ってきたときに、2のように各社員コードの年度の最大かつ期の最大で絞込みをしたいのですが、GROUP BYを使用してもうまく実現出来ません。
よろしければご教示願います。

DBはORCLEの11gになります。

1.JOINの取得結果
社員コード 社員名 年度 期
100 山田 2015 1
200 田中 2015 0
300 佐藤 2015 0
100 山田 2015 0
200 田中 2015 1
200 佐藤 2014 1

2.求めたい結果としては、以下の結果になります。
社員コード 社員名 年度 期
100 山田 2015 1
300 佐藤 2015 0
200 田中 2015 1

EKD, yng13, afroscript👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

unau

2016/02/11 06:07

結果としてどのような抽出になればいいのか、具体例を示していただけると曖昧性が減って回答しやすいと思います。
haru07

2016/02/11 06:22

求めたい結果の追記を致しました。ありがとうございます。
unau

2016/02/11 06:27

社員コードで GROUP BY して、その中で「年度 + 期」(たとえば年度が 2015 で期が 1 なら 20151 という数値として捉える) が最大になるレコードを抽出する、という理解でよいでしょうか。
guest

回答5

0

社員コード → 社員名
という関数従属性があれば、これでよさそうですね。

SQL

1select 社員コード,社員名, 2max(年度) as 年度, 3max() Keep(Dense_Rank Last order by 年度) as4 from JOINした結果 5group by 社員コード,社員名; 6

投稿2016/02/11 11:00

AketiJyuuzou

総合スコア1147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

haru07

2016/02/12 12:49

回答ありがとうございます。副問い合わせとKeep(Dense_Rank Last order by)で求めたい結果が得られました。
guest

0

ベストアンサー

KEEP(DENSE_RANK LAST)とGROUP BYを使う方法か、またはROW_NUMBER()で順番を付けた副問合せと結合して1番目だけ抽出する方法はいかがでしょうか。
SELECT項目が多い場合は、後者の方法の方が使い勝手が良いですが、「JOINの結果に対して絞込はしたい」という制約があると(いじれないビューになってるとかで)、前者の方法でしょうか。
KEEP(DENSE_RANK LAST)はORDER BY(年度と期の昇順)でソートした最後の行(つまり年度と期が最大の行)に対してMAX()をとっています。ORDER BYでソート順が一意に決まるならMAX()でもMIN()でも結果は同じです。

SQL

1SELECT r.syain_id AS "社員コード", 2 s.syain_name AS "社員名", 3 MAX(r.nendo) KEEP (DENSE_RANK LAST 4 ORDER BY r.nendo, r.ki) AS "年度", 5 MAX(r.ki) KEEP (DENSE_RANK LAST 6 ORDER BY r.nendo, r.ki) AS "期" 7FROM rireki r 8INNER JOIN syain s 9ON s.syain_id = r.syain_id 10GROUP BY r.syain_id, 11 s.syain_name 12ORDER BY r.syain_id

SQL

1WITH 2 sorted_rireki AS ( 3 SELECT r.syain_id, 4 r.nendo, 5 r.ki, 6 ROW_NUMBER() OVER(PARTITION BY r.syain_id 7 ORDER BY r.nendo DESC, r.ki DESC) AS row_num 8 FROM rireki r 9 ) 10SELECT sr.syain_id AS "社員コード", 11 s.syain_name AS "社員名", 12 sr.nendo AS "年度", 13 sr.ki AS "期" 14FROM sorted_rireki sr 15INNER JOIN syain s 16ON s.syain_id = sr.syain_id 17WHERE sr.row_num = 1 18ORDER BY sr.syain_id

投稿2016/02/11 10:38

q1701

総合スコア274

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

haru07

2016/02/12 12:50

回答ありがとうございます。副問い合わせとKeep(Dense_Rank Last order by)で求めたい結果が得られました。
guest

0

テーブル定義が不明なので、想像で書いてみました。
社員マスタテーブルには社員番号(社員コード)と社員名が、
年度マスタには社員番号(社員コード)、年度、期がある。
といったテーブル定義でやっています。

年度の最大だして、その後、最大年度内の期の最大とってあげればいいと思います。

oracle手元にないので、試してないですがおそらく行けると思います。

lang

1select 2 s.社員番号 3 , s.社員名 4 , n1.年度 5 , max(n2.期) 6from 7 社員マスタ s 8inner join 9 ( 10 select 11 社員番号 num 12 , max(年度) 年度 13 from 14 年度 15 group by 16 社員番号 17 ) n1 18 on 19 s.社員番号 = n1.num 20inner join 21 年度 n2 22 on 23 s.社員番号 = n2.社員番号 24 and 25 n1.年度 = n2.年度 26group by 27 s.社員番号 28 , s.社員名 29 , n1.年度

投稿2016/02/11 07:24

dt300m

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

haru07

2016/02/12 12:54

回答ありがとうございます。副問い合わせとKeep(Dense_Rank Last order by)で求めたい結果が得られました。
guest

0

SELECT * FROM TABLES ORDER BY 年数, 期 DESC

投稿2016/02/11 06:21

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

haru07

2016/02/11 06:29

JOINの結果に対して絞込はしたいので上記のSQLは使えません。申し訳ございません。 質問が分かりづらかったので修正致しました。回答ありがとうございます。
guest

0

Oralce は 10 年以上触っていないので忘れましたが、SQL においては 一般的に GROUP BY で集計して集計関数で計算した場合、集計したグループにおける平均値、最大値、最小値などしかわかりません。つまり、どのレコードが最大値だったのか、は集計関数を使ってもわかりません。
各グループにおける最大値のレコードを特定するためには副問合せが不可欠(のはず)です。

ご質問のケースで望ましい結果、やりたいことがはっきりわからないので具体的な SQL は書けませんが、考え方としては同一グループの中で最大のレコードを取得する SQL を書くということになります。


追記

こんな感じになるのかな、というのを書いてみました。Oracle が手元にないので未検証です。また、テーブル定義もわからないので、適当に想像して書いています。

sql

1SELECT outer_a.*, outer_b.*, outer_b.年度 * 10 + outer_b.AS outer_sortkey 2FROM table_a AS outer_a 3INNER JOIN table_b AS outer_b ON outer_a.社員コード = outer_b.社員コード 4WHERE NOT EXIST ( 5 SELECT inner_b.年度 * 10 + inner_b.AS inner_sortkey 6 FROM table_a AS inner_a 7 INNER JOIN table_b AS inner b ON inner_a.社員コード = inner_b.社員コード 8 WHERE outer_a.社員コード = inner_a.社員コード 9 AND outer_sortkey < inner_sortkey 10);

投稿2016/02/11 06:18

編集2016/02/11 06:52
unau

総合スコア2468

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問