よくある質問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 :
よくある質問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 :
よくある質問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ならこれを適当に改変すれば動きますが どのみちお奨めしません。
ある期間において注文してくれた顧客IDを、日付ごとに一覧するには、次のようにします。 select date(created_at), customer_id from sales_orders where date(created_at) between '2012-08-01' and '2012-08-07' group by date(created_at), customer_id order by date(created_at), customer_id ここで、ある期間において注文してくれた顧客数(重複を排除したユニーク数)を知るにはどうしたらいいでしょうか。
19 :
select count(distinct customer_id) from sales_orders where date(created_at) between '2012-08-01' and '2012-08-07'
select order_date, count(*) from ( select distinct date(created_at) as order_date, customer_id from sales_orders where date(created_at) between '2012-08-01' and '2012-08-07' ) group by order_date order by order_date; 試してないので無保証
こうかな select date(created_at), count(distinct customer_id) from sales_orders where date(created_at) between '2012-08-01' and '2012-08-07' group by date(created_at);
前スレよりコピペ 770* 名前:sage [] 投稿日:2012/06/21(木) 12:06:59.60 ID:oEiJL9az すまん、763です。具体的に言うと 株価Tab(時刻、株価) 為替Tab(時刻、$\為替レート) を株価のテーブルをメインにして SELECT時刻、株価、$|為替レート にしたいんだけど株価と為替の時刻は当然一致していないけど、 株価の時刻からみて最新の為替レートを表示したいんです。 よろしくおねがいします。 777 名前:NAME IS NULL [sage] 投稿日:2012/06/21(木) 19:14:27.33 ID:??? >>770 こうかな? select * from A T1 left outer join B T2 on T1.a1 >= T2.b1 where not exists ( select * from B T3 where T1.a1 >= T3.b1 and T2.b1 < T3.b1 ) order by a1 ;
select文では、joinを使えば複数のテーブルを使った条件式が指定できます。 -- Sales部門に属する従業員の一覧 select e.id, e.name, e.saraly from employees as e join departments as d on d.id = e.department_id where d.name = 'Sales';
同じことをupdate文でもしたいのですが、どうすればいいでしょうか。 -- Sales部門に属する従業員のデータを更新 update employees as e set saraly = saraly + 10 join departments as d on d.id = e.department_id where d.name = 'Sales';
副問い合わせを使えばできますけど、できればselect文と同じようにjoinを使って指定したいです。 update employees as e set saraly = saraly + 10 where e.department_id in (select id from departments where name = 'Sales');
t1 id str 1 a 2 b 3 c t2 id str 1 d 2 e 3 f t3 id t1.id t2.id 1 1 1 2 1 2 3 1 3 4 2 1 5 3 1 6 3 3 こういうテーブルがあります left joinで結合したところ t1.id t1.str t2.id t2.str t3.id 1 a 1 d 1 1 a 2 e 2 1 a 3 f 3 2 b 1 d 4 3 c 1 d 5 3 c 3 f 6 こうなりました これを t1.idが2でt2.idが2か3はnullなので入っていません 同様にt1.idが3でt2.idが2のとこもnullなので入っていません これを入れて t1.id t1.str t2.id t2.str t3.id 1 a 1 d 1 1 a 2 e 2 1 a 3 f 3 2 b 1 d 4 2 b 2 e null 2 b 3 f null 3 c 1 d 5 3 c 2 e null 3 c 3 f 6 こんな感じのを取得したいのですがどのようなSQLをかけばいいでしょうか? 使用DB SQLite3
プログラムからSQLの呼び出しについての質問ですが、 以下のSQLのテンプレートがあり、@〜Cにweb画面から渡された値を展開しています。 インジェクション対応していなかったようで、その対応を考えてます。 インジェクションでサブSQLを実行され情報漏えいできなければなんでもいいとのことで、 「(」だけをケアすればいいかなと思い、「(」を削除して Aは「'」を「''」にエスケープしますが、それ以外は「(」をカットしようかと考えています。 @とBにて、hogeの項目情報は公開されているので、他の項目を指定される文にはいいとの条件です。 select xx1, xx2 from hoge where @ = 'A' order by B C 「(」をカットだけすれば、とりあえず他テーブル情報を取得または更新されることは防げるでしょうか?
そうです、UPDATEでも INSERT INTO fruits (name,price) VALUES(りんご,150),(みかん,100) みたいな書き方で1回ですっきり出来る方法はないかなーと。 特にないのならご私的の通りこんな感じで行こうと思います。 BEGIN; UPDATE fruits SET price = 150 WHERE name = りんご; UPDATE fruits SET price = 100 WHERE name = みかん; END;
使用DB:mysql5 t1 id str 1 a 2 b 3 c t2 id t1.id t1.id 1 1 2 2 2 3 3 3 1 このふたつのテーブルを結合して id t1.id t1.str t1.id t1.str 1 1 a 2 b 2 2 b 3 c 3 3 c 1 a こういう結果を得る方法はありますか・・・? select * from t1 a INNER JOIN t2 b on b.id = a.id and b.id = a.id とやってみても、idが2つあるので結合出来ないです。