よくある質問1 (問) ID | DATE | DATA --+----------+----- 1 | 2007-11-11 | aaa 2 | 2007-11-11 | bbb 1 | 2007-11-10 | ccc 3 | 2007-11-12 | ddd 3 | 2007-11-11 | eee 4 | 2007-11-10 | fff 1 | 2007-11-12 | ggg このようなテーブルから、下記のように 1 | 2007-11-12 | ggg 3 | 2007-11-12 | ddd 2 | 2007-11-11 | bbb 4 | 2007-11-10 | fff 各idに対して最新の1件だけ抽出するSQLの書き方を教えてください。 (答) select A.ID, A.DATE, A.DATA from TableName A inner join (select ID, max(DATE) as MAX_DATE from TableName group by ID ) B on A.ID = B.ID and A.DATE = B.MAX_DATE ;
5 :11/09/23
よくある質問2 (問) key data ---------------- 1 a 1 a 1 b 1 b 1 a 2 b 2 a 2 a というテーブルから key a b -------------------- 1 3 2 2 2 1 というExcelのピボットの様なデータを取得したいのですが、どういうSQLになりますか? a,bというのは固定なので、仮にcというデータがあっても無視して構いません。 (答) SELECT key, SUM(CASE data WHEN 'a' THEN 1 END) AS a, SUM(CASE data WHEN 'b' THEN 1 END) AS b FROM table GROUP BY key ORDER BY key ;
6 :11/09/23
よくある質問3 (問) ID HOGE 01 A 01 B 01 C 02 A 03 B HOGEをAもBもCも持っている、ID:01だけ取り出すにはどうすればよかですか (答1) SELECT id FROM TableName WHERE hoge in ('A','B','C') GROUP BY id HAVING count(DISTINCT hoge) = 3 ; (答2) select * from TableName T1 where not exists (select * from (values 'A', 'B', 'C') T2 (HOGE) where not exists (select * from TableName T3 where T1.ID = T3.ID and T2.HOGE = T3.HOGE ) ) ; ※valuesの部分(Table Value Constructor)はDBMSによって文法がかなり違うので注意
よくある質問5 (問) 年月(YYYYMM)を指定し、その年月に対応する年月日を取得したい 例:201006を指定したら、以下の結果を得たい 20100601 20100602 ・ ・ ・ 20100630 (答) SQLでは存在しないデータを生成することはできません。 この問いの場合は素直にカレンダーテーブルを用意しましょう。 どうしてもやりたければ以下のような方法もなくはないですが、 再帰問合せの本来の使い方ではありません。 やめておくことを強くお奨めします。 (PostgreSQLのgenerate_series()関数なら辛うじてセーフかもしれませんが 賛否の分かれるところでしょう。) with TEMP (NUM) as ( select 1 from dual union all select NUM + 1 from TEMP where NUM < 31 ) select to_char(to_date('201006', 'YYYYMM') + NUM - 1, 'YYYYMMDD') from TEMP where to_date('201006', 'YYYYMM') + NUM - 1 < add_months(to_date('201006', 'YYYYMM'), 1) ; ※上記はOracleの場合です。(11gR2以降) ※再帰問合せをサポートするDBMSならこれを適当に改変すれば動きますが どのみちお奨めしません。
9 :11/09/23
以上、テンプレ終わり
10 :11/09/23
終了
11 :11/09/23
おつ
12 :11/09/23
ちん
13 :11/09/24
ぽこの
14 :11/09/24
さき
15 :11/09/25
っちょ
16 :11/09/25
ペロ
17 :11/09/25
なめ
18 :11/09/25
たい
19 :11/09/25
いいよ
20 :11/09/25
SQLマジSQL
21 :11/09/26
SQLマゾSQL
22 :11/09/27
まん
23 :11/09/27
ぼっ!!
24 :11/09/28
なめ
25 :11/09/28
よかった、SQLで悩んでる人はいなかったんだ
26 :11/09/28
いく
27 :11/09/28
でる
28 :11/09/28
のんで
29 :11/09/28
・DBMS名とバージョン MySQL 5.0 ・テーブルデータ userテーブル id int name varchar ・欲しい結果&説明 nameはユニークではないので、値が同じレコードが複数存在します。 nameの値が自分と同じ値を持つレコードが存在するレコードだけ全件抽出したいです 例) id name 1 aaa 2 bbb 3 ccc 4 bbb この場合idが2と4のレコードだけ抽出したいです。 どのようなSQLを書けばいいでしょうか。 よろしくお願いします。
30 :11/09/28
select * from user where name = 'bbb';
31 :11/09/28
ああー、意味がわかった select * from user where id in (select id from user group by name having count(*) > 1) こうかな
32 :11/09/28
where name in (select name以下略 の間違いだろ existsでもいい select * from user T1 where exists (select * from user T2 where T1.id <> T2.id and T1.name = T2.name) ;
すみません。WebPG板より誘導していただいてきました。質問させてください。 mysqlver5.1.6で update tbTest set flg=1 where seq_host = 524 AND non_printable=0 ORDER BY seq LIMIT 0 ,10 というのを実行しようとしたらmysqlではupdate文のoffsetができない?らしくエラーになりました。 これを実行(seqが特定のものから10個をフラグ建てたい) するにはどうしたらいいでしょうか?
38 :11/09/29
update文にORDER BYって
39 :11/09/29
またMySQLか
40 :11/09/29
>>37 ためしてないけど update tbTest set flg=1 where seq_host = 524 AND non_printable=0 AND seq in( select seq from tbTest t where (select COUNT(*) from tbTest where seq<t.seq)<10 ) updateのテーブルに別名付けれたり、updateにfromかけたりするともうちょっとすっきりするかもしれんが それは多分標準的なSQLじゃないだろうし
>>44 select ID, NAME, (select sum(AMOUNT) from 売り上げ where ID in (select ID from 得意先マスタwhere OYA_CODE=t.ID) ) as 合計 from 得意先マスタ t where ID=OYA_CODE とかでどうだ
>>49 いろいろと突っ込みどころ満載なんだがとりあえず SELECT 得意先名, (SELECT sum(明細金額) FROM 売伝明細 WHERE 売伝番号 in (SELECT 売伝番号 FROM 売伝 WHERE 親得意先コード = t.得意先コード) ) as 合計 FROM 売伝 t, WHERE 得意先コード=親得意先コード とか JOINでやりたいなら、得意先名いらなければ select 売伝.親得意先コード, sum(明細金額) as 合計 from 売伝 join 売伝明細 on 売伝.売伝番号=売伝明細.売伝番号 group by 売伝.親得意先コード とかでできるんじゃないか 得意先名ほしければ、これに得意先マスタ(あるだろ?)JOINしろ 売掛締年月はどうしたいのかわからん サブクエリにしてもJOINにしても、テーブルが紐付く条件よく考えてみることだ
この2つのSQLは等価だと思っていますが、まちがっていますか? mysql5.1 select * from tblA inner join (tblB left join tblC on tblB.out_c = tblC.key_c) on tblA.out_b = tblB.key_b select * from tblA inner join tblB on tblA.out_b = tblB.key_b left join tblC on tblB.out_c = tblC.key_c
61 :11/10/08
・DBMS名とバージョン PostgreSQL 9.0 ・テーブルデータ posts id post_tags post_id tag_id tags id tag(タグ文字列) ・欲しい結果 複数のタグ(tags.tag)を指定してAND検索でpostsを取得 ・説明 実際にはユーザテーブルも絡んだりしてもうちょっと複雑なのですが、タグ一つでの検索の場合は以下のような感じになると思います。 SELECT posts.* FROM posts JOIN post_tags ON post_tags.post_id = posts.id JOIN tags ON tags.id = post_tags.tag_id WHERE tags.tag = 'javascript' これを例えばタグ「javascript」とタグ「php」両方を持つpostを取得するにはどうしたら良いでしょうか?
>>61 かな〜り特殊な書き方だけどやってみた。 select * from ( select * from crosstab('SELECT posts.id,post_tags.tag_id, tags.tag FROM posts JOIN post_tags ON post_tags.post_id = posts.id JOIN tags ON tags.id = post_tags.tag_id ORDER BY 1, 2' ) AS ct( id integer, tag1 character varying, tag2 character varying,tag3 character varying, tag4 character varying) ) as t WHERE concat(tag1,tag2,tag3,tag4) LIKE '%javascript%' AND concat(tag1,tag2,tag3,tag4) LIKE '%php%' ちなみにconcatの部分は9.1じゃない場合はnullを除外して連結しなおす必要がある。 あと、crosstabを使ってるから、tablefuncモジュールインストールしないといけない。 最後のWHERE句は以下のように変更してもいける WHERE (tag1 = 'javascript' OR tag2 = 'javascript' OR tag3 = 'javascript' OR tag4 = 'javascript') AND (tag1 = 'php' OR tag2 = 'php' OR tag3 = 'php' OR tag4 = 'php')
64 :11/10/08
すなおに WHERE post_tags.tag_id in (SELECT id FROM tags where tag = 'javascript' ) AND post_tags.tag_id in (SELECT id FROM tags where tag = 'php' ) とかじゃいかんのか?
65 :11/10/08
>>62 JOINが増えてるだけでやろうとしてることは同じような感じでした! 参考にします、ありがとうございます >>63 crosstab初めて聞きました! まだSQL文を理解できてないですが、勉強してみます、ありがとうございます >>64 post_tagsを2回JOINすれば大丈夫そうです! SELECT posts.* FROM posts JOIN post_tags AS pt1 ON pt1.post_id = posts.id JOIN post_tags AS pt2 ON pt2.post_id = posts.id WHERE pt1.tag_id in (SELECT id FROM tags where tag = 'javascript' ) AND pt2.tag_id in (SELECT id FROM tags where tag = 'php' ) もしくはJOINだけでもいけました。 SELECT posts.* FROM posts JOIN post_tags AS pt1 ON pt1.post_id = posts.id JOIN tags AS t1 ON t1.id = pt1.tag_id JOIN post_tags AS pt2 ON pt2.post_id = posts.id JOIN tags AS t2 ON t2.id = pt2.tag_id WHERE t1.tag = 'javascript' AND t2.tag = 'php' パフォーマンステストをして方法を検討したいと思います 皆さんありがとうございました!
66 :11/10/08
post_tagsを2回もJOINする必要あるの?
67 :11/10/08
ない。
68 :11/10/09
掲示板のスクリプトをつくっています。 投稿のテーブルをつくり、 そこに1つの投稿へのレスもまとめて1つのテーブルに収めています。 設計としては以下のようになっています(説明のため多少シンプルにしています) 投稿テーブル ・id ID ・parent_id 上記のIDを外部キーとしたもの ・message 投稿内容 現在は 1.投稿テーブルから1ページに表示したい行を取得する SELECT * FROM posts WHERE parent_id IS NULL LIMIT 10 2.上記で取得した行の id を parent_id としている行を取得する SELECT * FROM posts WHERE parent_id = 1001; SELECT * FROM posts WHERE parent_id = 1002; SELECT * FROM posts WHERE parent_id = 1003; : つまり投稿1つに対してレスを探すためにSELECT文が1つ発行されており、 1ページ表示するのに 表示する投稿数+1 のSQL文が発行されてしまっています。 これを1つのSQL文で取得したいです。 別テーブルだとJOINでできるかと思いますが、同じテーブルでどうするのかがわかりません。 どういうSQL文にしたらよいでしょうか? MySQL 5.1.51です。
tblがひとつあり列は3つあります jinbutu、no、orderplan A 1 M A 2 N A 7 M B 3 N B 8 N B 9 N C 13 M C 14 N C 15 M C 16 N C 17 M このtblをdelete文で整理したいんですが jinbutuのなかでorderplanが同じ場合は noが一番小さいやつだけを残したいです ↓このようにしたい A 1 M A 2 N B 3 N C 13 M C 14 N よろしくお願いします
82 :11/10/14
delete from tbl where exists (select * from tbl T2 where tbl.jinbutu = T2.jinbutu and tbl.orderplan = T2.orderplan and tbl.no > T2.no) ;