外出自粛中でも楽しく過ごす!QAまとめ>>

ちょっと壁に当たったので、わかる範囲でお答え頂きたいのですが、
以下のようなテーブルがあったとします。

id user price date
1 A 1000 2013/5/31
2 A 1200 2013/6/1
3 B 1000 2013/5/20
4 A 1500 2013/5/12
5 C 1300 2013/5/31
6 C 1400 2013/5/14
7 C 1000 2013/5/6
8 B 1100 2013/5/24
9 B 1200 2013/5/30
10 B 1100 2013/5/4
11 A 1800 2013/4/12
12 C 900 2013/4/6
・・・

次に取得したいのは、

A 1200 2013/6/1
A 1000 2013/5/31
A 1500 2013/5/12
C 1300 2013/5/31
C 1400 2013/5/14
C 1000 2013/5/6
B 1200 2013/5/30
B 1100 2013/5/24
B 1000 2013/5/20

このようなデータなのですが、
条件:
1.userでグループ化したうちの日付降順で並べる
2.そのuserのデータの中で、日付降順で並べる
3.userのデータが複数あっても、取得するのは新しいものから3件のみ

この条件を満たすSQL文はどのように記述すればよいか、お知恵をお貸し下さい。
よろしくお願いします。

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

A 回答 (4件)

#1です。

少し訂正が有ります。

複数の user の最新の日付が同じ場合に、それらのuserのデータが混ざって出力される可能性が有るので、ORDER BY句に user も含めるべきでした。


SELECT * FROM tbl_hoge a
WHERE (SELECT COUNT(*) FROM tbl_hoge b WHERE a.user = b.user AND a.date < b.date) < 3
ORDER BY
(SELECT MAX(date) FROM tbl_hoge c WHERE a.user = c.user) DESC,
user,
date DESC
;
    • good
    • 2
この回答へのお礼

ありがとうございました!
希望通りの抽出が行えました。
実際のSQL文はもう少し複雑なのですが、提示して頂いた例を参考にアレンジさせて頂きました。
まだまだ勉強中の身ですので、またお世話になる際はよろしくお願いします。

お礼日時:2013/06/03 14:03

>3.userのデータが複数あっても、取得するのは新しいものから3件のみ



まで考えるとidも比較しなくてはいけないかもしれないですね

select * from テーブル as t1
where (select count(*) from テーブル as t2 where
t1.user=t2.user and
(t1.date<t2.date or t1.date=t2.date and t1.id<t2.id)
) <3
order by
(select max(`date`) from テーブル as t3 where t1.user=t3.user) desc
,user
,`date` desc
    • good
    • 0

http://note.chiebukuro.yahoo.co.jp/detail/n181988

参考にしてください。
CNT列はグルーピングごとにカウントアップするのでこれをWHERE条件で絞ればいいかなと思います。
    • good
    • 0

下記の様なSQLで出来るかと。


version 5.5.8 で確認しました。


SELECT * FROM tbl_hoge a
WHERE (SELECT COUNT(*) FROM tbl_hoge b WHERE a.user = b.user AND a.date < b.date) < 3
ORDER BY
(SELECT MAX(date) FROM tbl_hoge c WHERE a.user = c.user) DESC,
date DESC


> 1.userでグループ化したうちの日付降順で並べる

user 単位では最新の日付の降順になるということですよね?
ORDER BY句の自己結合で同じuserの中で最新の日付を取得して実現しています。

> 2.そのuserのデータの中で、日付降順で並べる

同一の user のデータ同士も日付の降順になるということですよね?
ORDER BY句の date DESC で実現しています。

> 3.userのデータが複数あっても、取得するのは新しいものから3件のみ

WHERE句の自己結合で実現しています。
同じuserでそれより新しい日付のデータが3件未満という意味です。

参考URL:http://codezine.jp/article/detail/460
    • good
    • 1

このQ&Aに関連する人気のQ&A

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

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

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

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

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

Qmysql5でGROUP BYごとにLIMIT??

2011,600
2011,500
2011,450
2011,750
2010,450
2010,540
2010,350
2010,800
2010,700

例えばこのようなデータを年ごとにベスト3までとって次のようにするSQLはありますか

2011,750
2011,600
2011,500
2010,800
2010,700
2010,540

Aベストアンサー

じゃあ、これを試してみてください。
select t.nen, t.gaku
from ( select
@rnk:=if(@prevnen <=> x.nen, if( @prevaku <=> x.gaku, @rnk, @rnk+1), 1 ) as rnk,
@prevnen := x.nen nen,
@prevgaku := x.gaku gaku
from ( select * from xxx order by nen, gaku desc ) as x
cross join ( select @prevnen:=0, @prevgaku:=0, @rnk:=0 ) as dummy ) t
where t.rnk <= 3;

Q上位3位を求めるSQL文は?

Mysqlのバージョンは4.0.14です。

次のようなテーブルがあります。
id   money
-----------------
1 2500
2 3200
1 1200
3 5000
4 2500
5 1200

IDでグループ化し、上位3件を抽出したいのです。
以下のように抽出したいのです。
Ranking id money
1 3 5000
2 1 3700
6 2 3200

SQLServerなら、上位何件かを取り出すには、
TOPを利用するようですが、
MYSQLにもそのようなものはないのでしょうか?

Aベストアンサー

limitがあります。

select * from table order by money desc limit 3

ですね。

あるいは limit 40,20なんて使い方もあります。これは「40件目から20件取得」という意味です。ページングに使えます。

QSELECT 文 GROUP での1件目を取得

非常に初歩的な事で恐縮ですが、
以下のデータを抽出するsql文の書き方を模索しています。
環境:SQLSERVER2005

| 列1| 列2 |
+---+---+
| 1 | A |
| 1 | B |
| 1 | C |
| 1 | D |
| 2 | F |
| 2 | G |
| 2 | H |
| 3 | X |
| 3 | Y |
| 3 | Z |

上記のテーブルがあるとします。
列1でグループした値で、1レコード目の列2を抽出したいのです。
出力結果としては、

列1列2
+--+--+
1,A
2,F
C,X

としたいのです。
列1でGROUPしてしまうと列2の内容を集約しないといけないので困っています。
ご教授いたけないでしょうか?

Aベストアンサー

SQL Server 2005では、Oracleでいう分析関数が実装されています。

select
列名1,
列名2
from
(select
rank() over(partition by 列1 order by 列2) as rk,
列1,列2
from 表名) as x
where rk=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.区分

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           ...続きを読む

QDBエラーの意味

フォームからDBにデータ挿入しようとすると

Column count doesn't match value count at row 1

というエラーが出てしまいます・・・どういう意味を持ったエラーなんでしょうか?

Aベストアンサー

カラム数と値の数が合わない、と言う事です。簡単な英語なので覚えましょう。
カラム数が4つにもかかわらず、
"INSERT INTO tablename VALUES (1,'hoge',3)"
とやった場合等に出るエラーだと思います。

QMySQL関数max()を条件にSELECTできませんか?

MySQL5.0を使っています。
次のようなテーブル(items)があるとします。

name(varchar)|number(int)
---------------------------
itemA | 5
itemB | 2
itemC | 3

ここからnumberの最大値を持つnameを抽出したいのです。
SELECT max(number) FROM items とすると当然「5」が返ってきますが、このmax(number)を条件にしてitemを抽出することはできないのでしょうか?

よろしくお願い申し上げます。

Aベストアンサー

select name, number from items order by number desc limit 1;

とか

select name from items a, (select max(number) from items) b where a.number = b.max;

ではどうでしょうか。

QMySQLで改行を含む文の登録のしかた(改行コード

MySQLで改行を含む文を登録したいんですが、改行を改行コードに書き換えて登録したいです。
改行コードはどのように書けばいいですか?

登録したい文:
あいうえお
かきくけこ
さしすせそ

Aベストアンサー

改行コードは¥nで登録すれば良いです。

Qillegal string offset

php5.3では動いていたプログラムをphp 5.4 で動かしたらwarning illegal string offsetが出て困っています。以下のプログラムでwarningが出ないようにするにはどのようにコーディングすればよいのでしょうか?


$a = array('exists' => 'foo');
if ($a['exists']['non_existent']) {
print 1;
}
print 2;
exit;

Aベストアンサー

isset()を使えばいいと思います

QWHERE句で結合。INNER JOINとの違い

MySQLで複数テーブルからデータ取得する際、
FROMの後に、テーブル名を2つ書いて、「WHERE」で繋げる書き方と、
「JOIN ★★ ON」で繋げる書き方では、何が違うのでしょうか?

・「INNER JOIN」と同じ意味でしょうか?
・書き方によっては、「LEFT OUTER JOIN」みたいにも書けるのでしょうか?

・普通は、どちらの書き方で書くとか、そういうお作法的な暗黙の了解はあるでしょうか?
・例えば「WHERE」だと3つ以上繋げられない(?)から、奨励されていない、とか…

Aベストアンサー

select *
from 表A, 表B
where 表A.列1 = 表B.列2 and 表A.列3 = 値



select *
from 表A inner join 表B on 表A.列1 = 表B.列2
where 表A.列3 = 値

は同じ結果となります。前者の方が古くからある構文,後者が新しい構文になります。新しいといっても20年は経っていますけれど。


> 普通は、どちらの書き方で書くとか、
> そういうお作法的な暗黙の了解はあるでしょうか?

旧構文は,結合を指定する要素がfrom句とwhere句に分かれてしまっているのに対して,
新構文では次のように各句の機能が明確ですから,join句の使用をお薦めします。

射影…select *
結合…from 表A inner join 表B on 表A.列1 = 表B.列2
選択…where 表A.列3 = 値


> 書き方によっては「LEFT OUTER JOIN」みたいにも書けるのでしょうか?

旧構文で外部結合を記述することもできますが,各データベース製品の独自構文になります。標準SQLの規格ではありません。


> 「WHERE」だと3つ以上繋げられない(?)から、奨励されていない、とか

そういう制限はありません。

select *
from 表A, 表B
where 表A.列1 = 表B.列2 and 表A.列3 = 値



select *
from 表A inner join 表B on 表A.列1 = 表B.列2
where 表A.列3 = 値

は同じ結果となります。前者の方が古くからある構文,後者が新しい構文になります。新しいといっても20年は経っていますけれど。


> 普通は、どちらの書き方で書くとか、
> そういうお作法的な暗黙の了解はあるでしょうか?

旧構文は,結合を指定する要素がfrom句とwhere句に分かれてしまっているのに対して,
新構文では次のように各句の機能が明確です...続きを読む


人気Q&Aランキング