Salesテーブル customer saleDate -------- ---------- Bill 1994/06/01 Fred 1994/06/01 Mary 1994/06/01 Bill 1994/06/02 Fred 1994/06/02 Bill 1994/06/03 Bill 1994/06/04 Bill 1994/06/05 Bill 1994/06/06 Bill 1994/06/07 Fred 1994/06/07 Mary 1994/06/08 Wendy 1999/10/05 Heidy 1999/10/10 Wendy 1999/10/15 Wendy 1999/10/20 Heidy 1999/10/25 Tiger 1999/10/30 customerごとで、 saleDateの最小と最大とレコード数と、saleDateの間隔の平均を出力する。 間隔がないcustomer(この場合は、Tiger)は、間隔の平均は、0とする customerテーブルのプライマリキーは、customerとsaleDateとする 出力結果 customer FirstSaleDate LastSaleDate SalesCount AvgSalesWait -------- ------------- ------------ ---------- ------------ Fred 1994/06/01 1994/06/07 2 1 Mary 1994/06/01 1994/06/08 2 3 Bill 1994/06/01 1994/06/07 7 7 Wendy 1999/10/05 1999/10/20 3 7.5 Heidy 1999/10/10 1999/10/25 2 15 Tiger 1999/10/30 1999/10/30 1 0
create table Sales( customer varchar2(5), saleDate date, primary key(customer,saleDate)); insert into Sales values('Bill', to_date('1994/06/01','yyyy/mm/dd')); insert into Sales values('Fred', to_date('1994/06/01','yyyy/mm/dd')); insert into Sales values('Mary', to_date('1994/06/01','yyyy/mm/dd')); insert into Sales values('Bill', to_date('1994/06/02','yyyy/mm/dd')); insert into Sales values('Fred', to_date('1994/06/02','yyyy/mm/dd')); insert into Sales values('Bill', to_date('1994/06/03','yyyy/mm/dd')); insert into Sales values('Bill', to_date('1994/06/04','yyyy/mm/dd')); insert into Sales values('Bill', to_date('1994/06/05','yyyy/mm/dd')); insert into Sales values('Bill', to_date('1994/06/06','yyyy/mm/dd')); insert into Sales values('Bill', to_date('1994/06/07','yyyy/mm/dd')); insert into Sales values('Fred', to_date('1994/06/07','yyyy/mm/dd')); insert into Sales values('Mary', to_date('1994/06/08','yyyy/mm/dd')); insert into Sales values('Wendy',to_date('1999/10/05','yyyy/mm/dd')); insert into Sales values('Heidy',to_date('1999/10/10','yyyy/mm/dd')); insert into Sales values('Wendy',to_date('1999/10/15','yyyy/mm/dd')); insert into Sales values('Wendy',to_date('1999/10/20','yyyy/mm/dd')); insert into Sales values('Heidy',to_date('1999/10/25','yyyy/mm/dd')); insert into Sales values('Tiger',to_date('1999/10/30','yyyy/mm/dd')); commit;
alter session set nls_date_format = 'yyyy/mm/dd'; select customer,min(SaleDate) as FirstSaleDate, max(SaleDate) as LastSaleDate, count(*) as SalesCount, case when count(*) = 1 then 0 else (max(SaleDate)-min(SaleDate)) / (count(*)-1) end as AvgSalesWait from Sales group by customer order by min(SaleDate),customer;
項数が2以上の、昇順にソートした数列で、 階差の平均をXとすると 末項 = 初項 + (項数 - 1) * X が成立するので 末項 = 初項 + (項数 - 1) * X ⇔ 末項 - 初項 = (項数 - 1) * X ⇔ (項数 - 1) * X = 末項 - 初項 ⇔ X = (末項 - 初項) / (項数 - 1) (項数 >= 2 ⇒ 項数-1 >0 なので) これと、 末項は、max(SaleDate) 初項は、min(SaleDate) 項数は、count(*) で求まることを使って、saleDateの間隔の平均を求めてます ■■■■■■■■■■■■■■■■■■■■■■■■■■ SQLは集合志向なので、基本的には、集合で考えるのですが、 ソートした数列で考えることも、時には必要ということでしょうか