このディレクトリの索引

# 出典 :: SQL質問応答スレ 12問目 #647 # #インデントが崩れる場合は http://ime.nu/pastebin.com/26BkXDHs をみてください。 # # -- # -- 商品テーブルと、 # -- # create table items ( # id serial primary key, # name varchar(255) not null, # price integer not null -- 単価 # ); # # -- # -- 販売テーブルがあるとする。 # -- # create table sales ( # id serial primary key, # item_id integer not null references items(id), # count integer not null default 1, -- 個数 # total integer not null, -- 単価 * 個数 # created_at timestamp not null default current_datetime # ) # # -- # -- 日付を指定して、その日の商品別販売金額合計を大きい順に表示したい。 # -- どういうSQLを書けばいいの? # -- こんなかんじで書けたらいいんだけど。 # -- # select items.id, items.name # from items, # (select item_id, sum(total) as sum_total # from sales # where date(created_at) = '2012-04-01' # group by item_id) as totals # where items.id = totals.item_id # order by totals.sum_total desc; # # items(110,モービルHI,130.0). items(210,モービルガス,120.0). items(8110,灯油,90.0). sales(3323,8110,80,7200.0,'2017-08-17'). sales(3324,210,15,1800.0,'2017-08-18'). sales(3325,110,10,1300.0,'2017-08-18'). sales(3326,210,10,1200.0,'2017-08-18'). '日付を指定して、その日の商品別販売金額合計を大きい順に表示したい' :- '日付を指定して、'(_日付), その日の商品別販売金額合計を大きい順に表示する(_日付,_合計金額_item_id_ならび). その日の商品別販売金額合計を大きい順に表示する(_日付,_合計金額_item_id_ならび) :- その日の商品別販売金額合計を(_日付,_合計金額_item_id_ならび), 大きい順に表示する(_日付,_合計金額_item_id_ならび). '日付を指定して、'(_日付) :- 催促付き整数入力('日付を8桁の整数で入力して下さい : ','8桁の整数'(_8桁の整数),_8桁の整数), '8桁の整数から日付を得る'(_8桁の整数,_日付),!. '日付を指定して、'(_日付) :- '日付を指定して、'(_日付). 催促付き整数入力(_催促,_制約,_整数) :- 催促付き行入力(_催促,_行), 整数入力検査(_行,_制約,_整数). 催促付き行入力(_催促,_行) :- write(_催促), 行入力(_行). 行入力(_行) :- read_line_to_codes(current_input,_文字コードならび), atom_codes(_行,_文字コードならび). 整数入力検査(_行,_制約,_整数) :- 行は整数に変換できて_制約を満たす(_行,_制約,_整数),!. 行は整数に変換できて_制約を満たす(_行,_制約,_整数) :- 行は整数に変換できて(_行,_整数),!, 整数入力制約(_制約). 行は整数に変換できて(_行,_整数) :- atom_number(_行,_整数),!. 行は整数に変換できて(_行,_) :- '入力が整数でないことを説明して、再入力を依頼して、偽となる。'(_行). '入力が整数でないことを説明して、再入力を依頼して、偽となる。'(_行) :- writef('入力された行 %w からは整数が得られません。再入力をお願いします。\n',[_行]), fail. 整数入力制約(_制約) :- call(_制約),!. 整数入力制約(_制約) :- writef('指定された制約 %t を満たしません。再入力をおねがいします。\n',[_制約]), fail. '8桁の整数'(_8桁の整数) :- integer(_8桁の整数), _8桁の整数 >= 10000000, _8桁の整数 =< 99999999. '8桁の整数から日付を得る'(_8桁の整数,_日付) :- swritef(_日付文字列,'%t',[_8桁の整数]), sub_atom(_日付文字列,0,4,_,_年), sub_atom(_日付文字列,4,2,_,_月), sub_atom(_日付文字列,6,2,_,_日), atomic_list_concat([_年,'-',_月,'-',_日],_日付),!. その日の商品別販売金額合計を(_日付,_合計金額_item_idならび) :- '_item_idならびを得る'(_item_idならび), その日の商品別販売金額合計を(_日付,_item_idならび,_合計金額_item_idならび). その日の商品別販売金額合計を(_日付,_item_idならび,_合計金額_item_idならび) :- findall([_合計金額,_item_id], '0ではない商品の販売合計'(_日付,_item_id,_item_idならび,_合計金額),_合計金額_item_idならび). '0ではない商品の販売合計'(_日付,_item_id,_item_idならび,_合計金額) :- member(_item_id,_item_idならび), 商品の販売合計(_日付,_item_id,_合計金額), _合計金額 =\= 0. '_item_idならびを得る'(_item_idならび) :- setof(_item_id,[_id,_item_id,_count,_total,_日付] ^ sales(_id,_item_id,_count,_total,_日付),_item_idならび). 商品の販売合計(_日付,_item_id,_合計金額) :- findsum(_total,sales(_id,_item_id,_count,_total,_日付),_合計金額). 大きい順に表示する(_日付,L1) :- 大きい順に(L1,L2), 表示する(_日付,L2). 大きい順に(L1,L2) :- msort(L1,L3), reverse(L3,L2). 表示する(_日付,L) :- forall((member([_合計金額,_id],L),items(_id,_name,_price)),writef('%w %w %20l %10r\n',[_日付,_id,_name,_合計金額])). findsum(A,B,C) :- findall(A,B,L), sum_list(L,C).