お世話になります。

現在、最新レコードを抽出し外部結合する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に変更)

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

このQ&Aに関連する最新のQ&A

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に関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QMAX関数を使ってからLEFT JOINしたいのですが・・

毎度お世話になります。
下記2つのテーブルからテーブル結合をして表示させたいのですが、その前にサブテーブルにある時間データの中で最新のものだけと結合したいと考えています。色々試したのですがうまくいきません。どなたかご教授の程よろしくお願いいたします。

main_tbl
| id | basyo | name |
---------------------
| 1 | 1  | aa  |
| 2 | 1  | bb  |
| 3 | 2  | cc  |
| 4 | 3  | dd  |

sub_tbl
| id | jyotai | time  |
------------------------
| 1 | 1   |12:25:30|
| 1 | 2   |13:15:12|
| 2 | 1   |13:20:14|
| 1 | 3   |13:50:08|

欲しい結果
| id | basyo | name | jyotai | time |
---------------------------------------
| 1 | 1  | aa  | 3   |13:50:08|
| 2 | 1  | bb  | 1   |13:15:12|
| 3 | 2  | cc  | null  | null |
| 4 | 3  | dd  | null  | null |

考えた構文
$sql = "SELECT main_tbl.id, main_tbl.basyo, main_tbl.name, sub_tbl.jyotai, sub_tbl.time FROM main_tbl LEFT OUTER JOIN (SELECT MAX(time) FROM sub_tbl GROUP BY id) ON main_tbl.id = sub_tbl.id";
または
$sql = "SELECT main_tbl.id, main_tbl.basyo, main_tbl.name, sub_tbl.jyotai, sub_tbl.time FROM main_tbl LEFT OUTER JOIN sub_tbl on main_tbl.id = sub_tbl.id WHERE SELECT MAX(time) FROM sub_tbl GROUP BY id";
または
$sql1 = "SELECT MAX(time) FROM sub_tbl GROUP BY id";
$rs1 = mysql_db_query($db,$sql1) or die("sql Error!");
$sql = "SELECT main_tbl.id, main_tbl.basyo,main_tbl.name, $rs1.jyotai, $rs1.time FROM main_tbl LEFT OUTER JOIN $rs1 ON main_tbl.id = $rs1.id";

~以下クエリの実行と表示文~

どれも駄目でした。(クエリエラー表示)

因みに結合のみとMAX関数を別々に実行すると表示できることを確認しています。

環境は
WinXP
Mysql5.0.41
php5.2.3
です。
まだまだ勉強中ですのでよろしくお願いいたします。

毎度お世話になります。
下記2つのテーブルからテーブル結合をして表示させたいのですが、その前にサブテーブルにある時間データの中で最新のものだけと結合したいと考えています。色々試したのですがうまくいきません。どなたかご教授の程よろしくお願いいたします。

main_tbl
| id | basyo | name |
---------------------
| 1 | 1  | aa  |
| 2 | 1  | bb  |
| 3 | 2  | cc  |
| 4 | 3  | dd  |

sub_tbl
| id | jyotai...続きを読む

Aベストアンサー

もう少しすっきりした文になるかも知れませんが、とりあえず以下のSQL文でどうでしょう。


select
m.id, m.basyo, m.name, y.jyotai, y.time
from
main_tbl m
left join ( select
s.id, s.jyotai, s.time
from
sub_tbl s,
( select
id, max(time) maxtime
from
sub_tbl
group by id) x
where s.id = x.id and s.time = x.maxtime) y
on m.id = y.id


■考え方
1.sub_tblから、id毎に最大時間のデータを抽出したテーブルを作成し、xとする。
select id, max(time) maxtime from sub_tbl group by id


2.xとsub_tblを等価結合することでsub_tblからid毎に最大時間を持つ行を抽出したテーブルを作成し、yとする。
select s.id, s.jyotai, s.time from sub_tbl s , x where s.id = x.id and s.time = x.maxtime

 ※この手順は、最大時間を持つ行のjyotaiを取得するため。


3.main_tblとyを外部結合する。
select m.id, m.basyo, m.name, y.jyotai, y.time from main_tbl m left join y on m.id = y.id

もう少しすっきりした文になるかも知れませんが、とりあえず以下のSQL文でどうでしょう。


select
m.id, m.basyo, m.name, y.jyotai, y.time
from
main_tbl m
left join ( select
s.id, s.jyotai, s.time
from
sub_tbl s,
( select
id, max(time) maxtime
from
sub_tbl
group by id) x
where s.id = x.id and s.t...続きを読む

Qテーブルの最後(最新)のレコードを抽出したい

宜しくお願いします。
PHP MYSQL の組み合わせで使っています

以下のようにして、最後のレコードを取り出したいのですが
まったく違う事をしているのかもしれません。

$sql =" select * from テーブル where フィールド='max' " ;

フィールドはauto_incrementで番号を振っています。
これで最大のつもりなのですが・・・。

他にも、レコードを入れた時間も記録したフィールドがあるのですが
どうしてよいか?判りません。

テーブルの最新のレコードを出したいのです。
**その中の一つのフィールドを取り出すのですが、
  それはうまくいっているみたいです 
  (max の所に数字を入れると表示します)

お手数かけますが、どなたかご教授お願いいたします。

Aベストアンサー

#2回答者です。

MySQL 4.1以前(サブクエリを使えない)なら、以下のような方法が考えられます。

select * from 表名
order by 列名 desc limit 1

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

Q各伝票に対して明細を1行目だけ表示したい

たびたびお世話になります。

仮に以下のようなテーブルを考えるとします。

○テーブルA (伝票)
伝票番号 (PK)
顧客コード

○テーブルB (伝票明細)
伝票番号 (PK)
伝票明細 (PK)
注文コード
大盛り区分

レストランなどでお客さんが注文した注文伝票を
想像していただければ良いかと思います。
一つの伝票番号に対して、複数の伝票明細があると。
DB上は上記のように格納するとします。

ここでテーブル結合を使って、各伝票の1行目の明細を表示しながら
SQL1発で抜いてきたいと思います。どういうSQLを考えたら良いでしょうか?

テーブルBの表示項目が1つだけなら、

SELECT A.伝票番号, A.顧客コード, (SELECT TOP 1 注文コード FROM テーブルB B WHERE A.伝票番号 = B.伝票番号)
FROM テーブルA A

で良いのですが、複数項目となるとどうやったら良いのか判りません。

Aベストアンサー

 テーブルBの1行目レコードというのを、どう定義するかによって、答えが変わると思います。
 
例えば、テーブルBの伝票明細が1から順にふられる数字であって、その伝票明細=1のものだけ取ってくれば良いというのであれば、SQL文はいたってシンプルになるかと思います。
 
 SELECT A.伝票番号,A.顧客コード,B.伝票明細,B.注文コード,B.大盛り区分
FROM テーブルA AS A
INNER JOIN テーブルB AS B
ON A.伝票番号=B.伝票番号
AND B.伝票明細=1

こんな感じでしょうか。

 伝票明細が1から始まらず、「TOP 1」を使うというのであれば

 SELECT A.伝票番号,A.顧客コード,B.伝票明細,B.注文コード,B.大盛り区分
FROM テーブルA AS A
INNER JOIN テーブルB AS B
ON A.伝票番号=B.伝票番号
WHERE B.伝票明細=(SELECT TOP 1 C.伝票明細 FROM テーブルB AS C WHERE B.伝票番号=C.伝票番号)

こんな感じになります。この場合EXIST使ったりIN使ったり、細かい事を言えば色々方法はあるかと思います。でも基本的な考えは同じようなものです。

 

 テーブルBの1行目レコードというのを、どう定義するかによって、答えが変わると思います。
 
例えば、テーブルBの伝票明細が1から順にふられる数字であって、その伝票明細=1のものだけ取ってくれば良いというのであれば、SQL文はいたってシンプルになるかと思います。
 
 SELECT A.伝票番号,A.顧客コード,B.伝票明細,B.注文コード,B.大盛り区分
FROM テーブルA AS A
INNER JOIN テーブルB AS B
ON A.伝票番号=B.伝票番号
AND B.伝票明細=1

こんな感じでしょうか。

 伝票明細が1か...続きを読む

QInner join と Left joinの明確な違いは?

Inner join と Left joinの違いがよくわかりません。
教えてください。

Aベストアンサー

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
4               NULL
5               NULL
6               NULL
の6レコードが出力されますが、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 INNER JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
の3レコードしか出力されません。

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3           ...続きを読む

Q最新日付のデータを取得したい

初心者でいまいちSQLが記述できませんでした。
どなたか教えてください。

以下のようなファイルから最新日付のデータを
取得したいのですが、どのようにSQLを記述したら
よいかわかりません。

個人番号|日付|名前|生年月日
00000001,2001/1/1,テスト太郎/1960/1/1
00000001,2003/1/1,テスト太郎/1960/1/1
00000001,2004/1/1,テスト太郎/1960/1/1
00000002,2002/1/1,テスト花子/1945/1/1
00000002,2003/1/1,テスト花子/1945/1/1
00000002,2005/1/1,ですと花子/1945/1/1
00000003,2001/1/1,テスト次郎/1980/1/1
00000003,2003/1/1,テスト次郎/1980/1/1
00000003,2005/1/1,テスト次郎/1980/1/1
↓抽出後
00000001,2004/1/1,テスト太郎/1960/1/1
00000002,2005/1/1,ですと花子/1945/1/1
00000003,2005/1/1,テスト次郎/1980/1/1

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

初心者でいまいちSQLが記述できませんでした。
どなたか教えてください。

以下のようなファイルから最新日付のデータを
取得したいのですが、どのようにSQLを記述したら
よいかわかりません。

個人番号|日付|名前|生年月日
00000001,2001/1/1,テスト太郎/1960/1/1
00000001,2003/1/1,テスト太郎/1960/1/1
00000001,2004/1/1,テスト太郎/1960/1/1
00000002,2002/1/1,テスト花子/1945/1/1
00000002,2003/1/1,テスト花子/1945/1/1
00000002,2005/1/1,ですと花子/1945/1/1
00000003,2001/1/1,テスト次...続きを読む

Aベストアンサー

8i workgroup だと、分析関数が使えません。9i以降は、standard(旧workgroup)でも使えますが。以下、代替え法です。

・個人番号毎に日付が単一(同一日なし)なのであれば、
select 個人番号,日付,名前,生年月日
from TARGET
where
(個人番号,日付) in (select 個人番号,max(日付) from TARGET group by 個人番号)
;

Q3つの表の外部結合

表A、B、Cの3つがあり、Aのすべての行を出力したいと考えています。
外部結合を用いるのだとは思うのですが、3つの表に対して行う場合の
書き方がわからず困っています。
ご教授いただけないでしょうか?
select * from a,b,c
where a.商品ID =b.商品ID (+) and b.商品ID (+) =c.商品ID (+)
としてみましたが、うまくいきませんでした。

Aベストアンサー

ansi構文の趣旨からいえば、結合条件と絞り込み条件は分けて書くので・・

select *
from a
left join b on (a.商品ID =b.商品ID)
left join c on (b.商品ID =c.商品ID)
where a.年月 = 任意の値

と書くのが一般的でしょうね。

QSQL文について(片方のテーブルに存在しないレコード抽出)

以下のような2つのテーブルがあったとして、
2つともに存在する「店コード」を抽出するのはSQLは分かるのですが、
片方に存在しない「店コード」(以下の例の場合、「2」)を抽出するSQLを
一文で書くにはどうすればいいのでしょうか?

<店テーブル>
店コード住所・・・(その他、基本情報)
1aaa
2bbb
3ccc

<販売テーブル>
店コード販売品目・・・(その他、販売数など)
1xxx
3zzz

Aベストアンサー

オプティマイザ次第だけど、NOT-INは、あまりお勧めでない。
外部結合も索引があっても有効に使われないので、お勧めでない。

select * from A where not exists(select 1 from B where A.店コード=B.店コード);

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

お世話になります。

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
テーブル名
)
----------------------------------
但し、上記の場合、
社員ごとに最大値レコードが取得できません。

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

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

お世話になります。

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

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

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

Aベストアンサー

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

QID毎に最新の値を取得する

はじめて質問させていただきます。
現在、MySQLを使って会員管理用DBを作成しており、以下のようなテーブルを作っています。

ID | Name | Address | UpdateDate
1 | A | 東京 | 2009-10-10
1 | A | 福岡 | 2009-10-11
2 | B | 東京 | 2008-09-02

このようなID毎に複数のデータがある状態で、各IDの最新のデータのみを取得したいのですが、方法がわからずにいます。
大変初歩的な質問かもしれませんが、方法をご存じの方どうかご教授ください。
また、素人なもので、質問の方法が悪いかもしれません。その場合、ご指摘いただければ幸いです。

よろしくお願いします。

Aベストアンサー

>最新のデータのみを取得したい

SELECT * FROM hoge
WHERE (id,UpdateDate) IN
(SELECT id,max(UpdateDate) FROM hoge GROUP BY id)


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング