こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

日付の最大値レコードを取得する方法について

お世話になります。

SQLで日付の最大値を取得する方法です。

テーブルのデータ内容は以下のようになっています。

| 社員番号 | 社員名 | 日付 | 順序 |
+---------+-------+-----------+-----+
| 100 | AAA | 2011/05/01 | 2 |   ← このレコードを取得したい
+---------+-------+-----------+-----+
| 100 | AAA | 2011/05/01 | 1 |
+---------+-------+-----------+-----+
| 100 | AAA | 2011/04/01 | 1 |
+---------+-------+-----------+-----+
| 200 | BBB | 2011/04/01 | 2 |   ← このレコードを取得したい
+---------+-------+-----------+-----+
| 200 | BBB | 2011/04/01 | 1 |
+---------+-------+-----------+-----+

取得したいレコードは、
社員ごとの最大日付の最大順序をもつレコードです。
(上記の1行目と4行目のレコードを取得したい)

この場合、
下記のようなSQLを考えます。
---------------------------------
SELECT
社員番号, 社員名, 日付
FROM
テーブル名
WHERE
社員番号 = 'xxx'
AND 日付 = (SELECT
MAX(日付)
FROM
テーブル名
)
AND 順序 = (SELECT
MAX(順序)
FROM
テーブル名
)
----------------------------------
但し、上記の場合、
社員ごとに最大値レコードが取得できません。

どなたかレコード取得方法について
教えていただけないでしょうか?

よろしくお願いいたします。

投稿日時 - 2011-06-05 10:33:14

QNo.6787434

すぐに回答ほしいです

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

WINDOW関数が使えるなら
SELECT 社員番号, 社員名, 日付, 順序
FROM
( SELECT *, ROW_NUMBER() OVER( PARTITION BY 社員番号 ORDER BY 順序 DESC ) RN
FROM テーブル )
WHERE RN = 1 ORDER BY 社員番号;

投稿日時 - 2011-06-05 18:14:03

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

ANo.4のbaunceです。すみません。

他の方が回答されている事に気づきませんでした。
nora1962さんの回答と同じでした。

nora1962さんごめんなさい

大変失礼しました。

投稿日時 - 2011-06-07 00:07:28

ANo.4

こんばんは。
私も先ほどこちらに質問させていただいたのですが、
私にも回答できそうな質問があったので協力させていただきます。

◇まずは検証データ作成。

create table EX001
(
C1 number,
c2 varchar2(8),
c3 date,
c4 number
);

insert all
into ex001(c1,c2,c3,c4) values(100,'AAA',to_date('2011/0501'),2)
into ex001(c1,c2,c3,c4) values(100,'AAA',to_date('2011/0501'),1)
into ex001(c1,c2,c3,c4) values(100,'AAA',to_date('2011/0401'),1)
into ex001(c1,c2,c3,c4) values(200,'BBB',to_date('2011/0401'),2)
into ex001(c1,c2,c3,c4) values(200,'BBB',to_date('2011/0401'),1)
select 'X' from dual;

commit;

◇回答SQL

select * from
(
select c1,c2,c3,c4,row_number() over (partition by c1 order by c3 desc,c4 desc) jyun
from ex001 order by c2,jyun
) t where t.jyun = 1;

C1 C2 C3 C4 JYUN
---------- -------- -------- ---------- ----------
100 AAA 11-05-01 2 1
200 BBB 11-04-01 2 1

これでどうでしょうか?
とりあえず意図する行は返ると思いますが、
一社員の中で1位が2レコードあった場合などは
考慮できてないです。

投稿日時 - 2011-06-06 23:48:14

ANo.2

「同じ社員番号で、後の日付のデータが無く、同じ日付でより大きい順序のデータも無いもの」という条件を相関サブクエリを使って表現すればよいかと。

例) ---------------------------------------------
SELECT * FROM テーブル名 e1
WHERE
NOT EXISTS(
SELECT * FROM テーブル名 e2
WHERE e1.社員番号 = e2.社員番号
AND (e1.日付 < e2.日付 OR e1.日付 = e2.日付 AND e1.順序 < e2.順序)
);
---------------------------------------------


ちなみに社員番号でグループ化して、日付と順序のMAXを取得した場合は、日付と順序おのおのの最大値が返されるため、期待されるものと違う結果になるかも知れません。

--------------------------
| 100 | AAA | 2011/05/01 | 2 |
--------------------------
| 100 | AAA | 2011/05/01 | 1 |
--------------------------
| 100 | AAA | 2011/04/01 | 3 |
--------------------------
| 100 | AAA | 2011/04/01 | 2 |
--------------------------
| 100 | AAA | 2011/04/01 | 1 |
--------------------------

このような状態だった場合、グループ化する方法だと下記の様な結果になります。

--------------------------
| 100 | AAA | 2011/05/01 | 3 |
--------------------------

参考URL:http://codezine.jp/article/detail/907

投稿日時 - 2011-06-05 15:09:57

ANo.1

こういうことでしょうか?

SELECT
社員番号
, 社員名
, MAX(日付)
, MAX(順序)
FROM
テーブル名
GROUP BY
社員番号
, 社員名

投稿日時 - 2011-06-05 10:52:28

あなたにオススメの質問