プロが教える店舗&オフィスのセキュリティ対策術

お世話になります。

現在、最新レコードを抽出し外部結合するSQLを考えているのですが、実現できておりません。
実現できるSQLをご存知の方、いらっしゃいましたら情報を頂けますでしょうか。
# 私の使用しているのは、PostgreSQL8.3となります。

実現したい内容は、以下となります。
 1.テーブルAから「名前」でグループ化して最新の「更新日付」のレコードを抽出。
 2.1の結果とテーブルBを「名前」で結合。
 3.テーブルAの「名前」、「点数」、「更新日付」とテーブルBの「判定」を抽出。
   ⇒ただしテーブルAに情報がある場合は、テーブルBの判定結果を「0」にして出力。


     テーブルA               テーブルB
----------------------------   -----------------------
 名前| 点数| 更新日付       名前 | 判定 
----------------------------   -----------------------
AAA   98   2011/4/1        AAA   0 
AAA   60   2011/4/3        BBB   1 
BBB   70   2011/4/2        CCC   1 
BBB   35   2011/4/4        DDD   1 
DDD   98   2011/4/1        EEE   0 
EEE   47   2011/4/5         FFF   0 
GGG   80   2011/4/6        GGG   1 

 
【出力結果】
---------------------------------------------
 名前 | 点数  | 更新日付 | 判定 
---------------------------------------------
AAA    60     2011/4/3      0 
BBB    35     2011/4/4     0(1⇒0に変更) 
CCC   NULL     NULL       1 
DDD    98     2011/4/1     0(1⇒0に変更) 
EEE    47     2011/4/5      0 
FFF    NULL     NULL       0 
GGG    80     2011/4/6     0(1⇒0に変更)

お手数お掛け致しますが、ご教示のほどよろしくお願い致します。

A 回答 (2件)

PostgreSQL 8.3 ですと、「最新の「更新日付」のレコードを抽出」の箇所でセルフジョインが必要になります。



具体的なSQLはこのような感じです。最新の日付を max() で計算しているので、更新日付のデータ型を date にするか、文字列の場合はゼロ埋め ("2011/04/03") しておいてください。

CREATE TABLE テーブルA (名前 text, 点数 integer, 更新日付 date);
INSERT INTO テーブルA VALUES
('AAA', 98, '2011/4/1'),
('AAA', 60, '2011/4/3'),
('BBB', 70, '2011/4/2'),
('BBB', 35, '2011/4/4'),
('DDD', 98, '2011/4/1'),
('EEE', 47, '2011/4/5'),
('GGG', 80, '2011/4/6');

CREATE TABLE テーブルB (名前 text, 判定 integer);
INSERT INTO テーブルB VALUES
('AAA', 0),
('BBB', 1),
('CCC', 1),
('BBB', 1),
('DDD', 0),
('EEE', 0),
('GGG', 1);

SELECT
名前, 点数, 更新日付,
CASE WHEN max_a.名前 IS NOT NULL THEN 0 ELSE 判定 END AS 判定
FROM
(SELECT 名前, max(更新日付) AS 更新日付 FROM テーブルA GROUP BY 名前) AS max_a
JOIN
テーブルA USING (名前, 更新日付)
RIGHT JOIN テーブルB USING (名前);
    • good
    • 0
この回答へのお礼

お礼が遅くなり申し訳ありません。

ご回答ありがとうございます。
頂いたSQLで実現できました。また、更新日付のデータ型についても了解致しました。

ご協力ありがとうございました。

お礼日時:2011/05/11 17:37

最新レコードを抽出するのにnot existsを使う方法もありますね。


そこの部分以外はgacky-79さんのSQLをそのまま使わせていただきました。

SELECT
名前, 点数, 更新日付,
CASE WHEN max_a.名前 IS NOT NULL THEN 0 ELSE 判定 END AS 判定
FROM
(SELECT * FROM テーブルA AS A1
WHERE NOT EXISTS(
SELECT * FROM テーブルA AS A2
WHERE A1.名前 = A2.名前 AND A1.更新日付 < A2.更新日付
)) AS テーブルA
RIGHT JOIN テーブルB USING (名前);
    • good
    • 0
この回答へのお礼

お礼が遅くなり申し訳ありません。

ご回答ありがとうございます。
not existsを使用しても実現可能なんですね。性能面も考えて
NO.1の方のとどちらを使用するか検討させて頂きます。

ご協力ありがとうございました。

お礼日時:2011/05/11 17:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す