このディレクトリの索引

% 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1295436346/173 # # 質問させてください # selectしたデータを一部だけ別のテーブルに入れる方法ってありますか? # # 例:insert into table2 (aaa,bbb,ccc) select aaa as aaa,bbb as bbb,ccc as ccc from table1 # この場合table1のデータがすべてtable2に入るのでaaaだけ別のデータを入れたいと思っています。 # よろしくお願いします。 # # 海に接していない都道府県名([栃木県,群馬県,埼玉県,山梨県,長野県,岐阜県,滋賀県,奈良県]). table1(奈良県,1000,aa). table1(埼玉県,2000,ab). selectしたデータを一部だけ別のテーブルに入れる方法 :- 海に接していない都道府県名(_海に接していない都道府県名ならび), table1(_都道府県名の一,_bbb,_ccc), 新しい都道府県名の生成(_海に接していない都道府県名ならび,_都道府県名の一,_都道府県名の二), assertz(table2(_都道府県名の二,_bbb,_ccc)), fail. selectしたデータを一部だけ別のテーブルに入れる方法. 新しい都道府県名の生成(_海に接していない都道府県名ならび,_都道府県名の一,_都道府県名の二) :- M is (random mod 8) + 1, list_nth(M,_海に接していない道府県名ならび,_都道府県名の二), \+(_都道府県名の一 = _都道府県名の二), \+(table2(_都道府県名の二,_,_)). 新しい都道府県名の生成(_海に接していない都道府県名ならび,_都道府県名の一,_都道府県名の二) :- 新しい都道府県名の生成(_海に接していない都道府県名ならび,_都道府県名の一,_都道府県名の二). # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/584 # # MySQL 5.5.19 . 長くなりますので # テーブルの定義・内容と欲しい結果はここに # http://ime.nu/codepad.org/oe1jhVrF # # で、 # # create table a_tbl( # code int(9) not null, # input_date date not null, # data1 double(9,2) unsigned default 0 not null, # data2 double(9,2) unsigned default 0 not null, # primary key(code,input_date) # ) ; # # insert into a_tbl # values # (1111,'2012-02-01',10,12), # (1111,'2012-02-02',133,14), # (1111,'2012-02-04',13,15), # (1111,'2012-02-06',13,10); # # create table b_tbl( # code varchar(10) not null, # input_date date not null, # data1 double(9,2) unsigned default 0 not null, # data2 double(9,2) unsigned default 0 not null, # primary key(code,input_date) # ) ; # # insert into b_tbl # values # ('ddd','2012-02-01',122,13), # ('ddd','2012-02-03',127,18), # ('ddd','2012-02-04',11,14), # ('ddd','2012-02-05',16,95), # ('ddd','2012-02-06',13,10); # # 欲しい結果 # input_date a.data1 a.data2 b.data2 # 2012-02-01 10 12 13 # 2012-02-02 133 14 null # 2012-02-03 null null 18 # 2012-02-04 13 15 14 # 2012-02-05 null null 95 # 2012-02-06 13 10 10 # # # select a.input_date,b.input_date,a.data1,a.data2,b.data2 # from a_tbl a # right join b_tbl b # on a.input_date = b.input_date; とすると、結果が # +------------+------------+-------+-------+-------+ # | input_date | input_date | data1 | data2 | data2 | # +------------+------------+-------+-------+-------+ # | 2012-02-01 | 2012-02-01 | 10 | 12 | 13 | # | NULL | 2012-02-03 | NULL | NULL | 18 | # | 2012-02-04 | 2012-02-04 | 13 | 15 | 14 | # | NULL | 2012-02-05 | NULL | NULL | 95 | # | 2012-02-06 | 2012-02-06 | 13 | 10 | 10 | # +------------+------------+-------+-------+-------+ # なんですが、実際にはいろんなコードが入っているので、コードも抽出条件に入れたら # select a.input_date,b.input_date,a.data1,a.data2,b.data2 # from a_tbl a # right join b_tbl b # on a.input_date = b.input_date # where # a.code=1111 and b.code='ddd'; # +------------+------------+-------+-------+-------+ # | input_date | input_date | data1 | data2 | data2 | # +------------+------------+-------+-------+-------+ # | 2012-02-01 | 2012-02-01 | 10 | 12 | 13 | # | 2012-02-04 | 2012-02-04 | 13 | 15 | 14 | # | 2012-02-06 | 2012-02-06 | 13 | 10 | 10 | # +------------+------------+-------+-------+-------+ # になってしまいました。 # コードを抽出条件に入れた状態で望ましい結果または上の方の結果になるようなSQLを教えて下さい。 # 'input_dateの集合を得る'(_input_dateの集合) :- findall(_input_date,a_tbl(_input_date,_,_),L1), findall(_input_date,b_tbl(_input_date,_,_),L2), append(L1,L2,L3), setof(_input_date,member(_input_date,L3),_input_dateの集合). 抽出(_input_date,_tbl_aのdata1ならび,_tbl_aのdata2ならび,_tbl_bのdata2ならび) :- 'input_dateの集合を得る'(_input_dateの集合), member(_input_date,_input_dateの集合), findall([_data1],tbl_a(_,_input_date,_data1,_),_tbl_aのdata1ならび), findall([_data2],tbl_a(_,_input_date,_,_data2),_tbl_aのdata2ならび), findall([_data2],tbl_b(_,_input_date,_,_data2),_tbl_bのdata2ならび). # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/633 # # MySQL 5.1です。 # # create table staff_list( # staff_id int(5) primary key //社員番号 # staff_name varchar(8) //社員名 # unit varchar(8) primary key //部署名 # ) # # insert into staff_list (staff_id,staff_name,unit) values # (1,'範馬','総務'), # (2,'愚地','総務'), # (3,'花山','総務'), # (1,'高津','企画'), # (2,'池谷','企画'), # (3,'長嶋','企画'), # (1,'鳩山','営業'), # (2,'野田','営業'), # (3,'小沢','営業'), # (4,'枝野','営業') # # # # このようなテーブルに対してSELECTをかける際、一度のクエリーで # 部署別にソートしたうえで、総務だけstaff_id降順で他を昇順で出したいと思っています。 # # order by unit,IF(staff_name='総務',staff_id desc,staff_id asc) # などと試行してみているのですがうまくできません。 # # どなたかうまい方法をご存じないでしょうか。 # # よろしくお願いいたします。 # スタッフリスト(1,範馬,総務). スタッフリスト(2,愚地,総務). スタッフリスト(3,花山,総務). スタッフリスト(1,高津,企画). スタッフリスト(2,池谷,企画). スタッフリスト(3,長嶋,企画). スタッフリスト(1,鳩山,営業). スタッフリスト(2,野田,営業). スタッフリスト(3,小沢,営業). スタッフリスト(4,枝野,営業). 'このようなテーブルを選択する際、一度部署別にソートしたうえで、総務だけ社員番号降順で出したいと思っています。'(_部署名,_社員番号,_社員名) :- 一度部署別にソートしたうえで(_部署名ならび), 総務だけ社員番号降順で出したい(_部署名ならび,_部署名,_社員番号,_社員名). 一度部署別にソートしたうえで(_部署名ならび) :- findsetof(_部署名,( スタッフリスト(_社員番号,_社員名,_部署名)), _部署名ならび). 総務だけ社員番号降順で出したい(_部署名ならび,_部署名,_社員番号,_社員名) :- member(_部署名,_部署名ならび), 総務だけ社員番号降順で出したい(_部署名,_社員番号,_社員名). 総務だけ社員番号降順で出したい(総務,_社員番号,_社員名) :- 総務だけ社員番号降順で(_社員番号,_社員名). 総務だけ社員番号降順で出したい(_部署名,_社員番号,_社員名) :- \+(_部署名 == 総務), スタッフリスト(_社員番号,_社員名,_部署名). 総務だけ社員番号降順で(_社員番号,_社員名) :- findall([_社員番号,_社員名],( スタッフリスト(_社員番号,_社員名,総務)), L1), 降順でソート(L1,L2), member([社員番号,_社員名],L2). 降順でソート(L1,L2) :- sort(L1,L3), reverse(L3,L2). % % findsetof/3 % # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/666 # # SQLite3を使っています。 # # カラムがなかったらinsert # あったらupdateしたいのですが、 # どういうSQLをかけばいいのでしょうか? # # insert into t1(c1, c2) values("hoge",10) # update t1 set c2=10 WHERE c1="hoge" # このときc1はuniqueです。 # # よろしくお願いします。 # # 'カラムがなかったらinsert あったらupdateしたい'(_テーブル,_カラムならび,_鍵カラム,_鍵値) :- findall(_カラム,( テーブル定義(_テーブル,_番目,_カラム)), L1), 鍵値をセットする(_テーブル,_鍵カラム,_鍵値,P), 'カラムがなかったらinsert あったらupdateしたい'(P,_テーブル,_カラムならび). 鍵値をセットする(_テーブル,L1,_鍵カラム,_鍵値,P) :- length(L1,Len), length(L2,Len), nth1(Nth,L1,_鍵カラム), nth1(Nth,L2,_鍵値), P =.. [_テーブル|L2]. 'カラムがなかったらinsert あったらupdateしたい'(P,_テーブル,_カラムならび) :- call(P),!, ( retract(P), Q =.. [_テーブル|_カラムならび], asserta(Q), fail; true). 'カラムがなかったらinsert あったらupdateしたい'(_,_テーブル,_カラムならび) :- Q =.. [_テーブル|_カラムならび], asserta(Q). # 出典:: http://toro.2ch.net/test/read.cgi/db/1343899481/684 # # ・DBMS名とバージョン # Oracle 10g # ・テーブルデーた # create table aaa ( # id number(5,0) primary key, -- 主キー # nendo char(4), -- 年度 # tsuki char(2) -- 月 # ); # insert into aaa values (1, '2012', '01'); # insert into aaa values (2, '2012', '02'); # insert into aaa values (3, '2012', '03'); # insert into aaa values (4, '2012', '04'); # insert into aaa values (5, '2012', '05'); # ・欲しい結果 # id, nendo, tsuki # -------------------- # 4, '2012', '04' # 5, '2012', '05, # 1, '2012', '01' # 2, '2012', '02' # 3, '2012', '03' # # ・説明 # 年度/月の昇順に並べたいです。 # 2012年度3月は2013年3月、2012年度4月は2012年4月となるのでただの大小比較では無理でした。 # '・テーブルデータ create table aaa ( id number(5,0) primary key, -- 主キー nendo char(4), -- 年度 tsuki char(2) -- 月 ); insert into aaa values (1, '2012', '01'); insert into aaa values (2, '2012', '02'); insert into aaa values (3, '2012', '03'); insert into aaa values (4, '2012', '04'); insert into aaa values (5, '2012', '05'); ・欲しい結果 id, nendo, tsuki -------------------- 4, '2012', '04' 5, '2012', '05, 1, '2012', '01' 2, '2012', '02' 3, '2012', '03' ・説明 年度/月の昇順に並べたいです。 2012年度3月は2013年3月、2012年度4月は2012年4月となるのでただの大小比較では無理でした。'(_id,_年度,_月) :- 欲しい結果(_id,_年度,_月). 年度の場合の月順('04','05'). 年度の場合の月順('05','06'). 年度の場合の月順('06','07'). 年度の場合の月順('07','08'). 年度の場合の月順('08','09'). 年度の場合の月順('09','10'). 年度の場合の月順('10','11'). 年度の場合の月順('11','12'). 年度の場合の月順('12','01'). 年度の場合の月順('01','02'). 年度の場合の月順('02','03'). 年度の場合の月順('03','04'). 欲しい結果(_id,_年度,_月) :- findsetof(_年度,aaa(_,_年度,_),_年度ならび), member(_年度,_年度ならび), 年度順に並べる('04',_id,_年度,_月). 年度順に並べる(_月,_id,_年度,_月) :- aaa(_id,_年度,_月). 年度順に並べる(_月_1,_id,_年度,_月) :- \+(_月_1 = '03'), 年度の場合の月順(_月,_次の月), 年度順に並べる(_次の月,_id,_年度,_月). # 出典:: http://toro.2ch.net/test/read.cgi/db/1343899481/684 # # ・DBMS名とバージョン # Oracle 10g # ・テーブルデーた # create table aaa ( # id number(5,0) primary key, -- 主キー # nendo char(4), -- 年度 # tsuki char(2) -- 月 # ); # insert into aaa values (1, '2012', '01'); # insert into aaa values (2, '2012', '02'); # insert into aaa values (3, '2012', '03'); # insert into aaa values (4, '2012', '04'); # insert into aaa values (5, '2012', '05'); # ・欲しい結果 # id, nendo, tsuki # -------------------- # 4, '2012', '04' # 5, '2012', '05, # 1, '2012', '01' # 2, '2012', '02' # 3, '2012', '03' # # ・説明 # 年度/月の昇順に並べたいです。 # 2012年度3月は2013年3月、2012年度4月は2012年4月となるのでただの大小比較では無理でした。 # '・テーブルデータ create table aaa ( id number(5,0) primary key, -- 主キー nendo char(4), -- 年度 tsuki char(2) -- 月 ); insert into aaa values (1, '2012', '01'); insert into aaa values (2, '2012', '02'); insert into aaa values (3, '2012', '03'); insert into aaa values (4, '2012', '04'); insert into aaa values (5, '2012', '05'); ・欲しい結果 id, nendo, tsuki -------------------- 4, '2012', '04' 5, '2012', '05, 1, '2012', '01' 2, '2012', '02' 3, '2012', '03' ・説明 年度/月の昇順に並べたいです。 2012年度3月は2013年3月、2012年度4月は2012年4月となるのでただの大小比較では無理でした。'(_id,_年度,_月) :- 欲しい結果(_id,_年度,_月). 欲しい結果(_id,_年度,_月) :- findsetof(_年度,aaa(_,_年度,_),_年度ならび), member(_年度,_年度ならび), 年度順に並べる(['04','05','06','07','08','09','10','11','12','01','02','03'],_id,_年度,_月). 年度順に並べる([_月|R],_id,_年度,_月) :- aaa(_id,_年度,_月). 年度順に並べる([_|R],_id,_年度,_月) :- 年度順に並べる(R,_id,_年度,_月). # 質問です。 # MySQL5です。 # テーブルデータはDATE(YYYYMMの6けたのint型),CODE(varchar型),VALUE(varchar型) の3カラムからなります。 # 各日付順の降順にしたいのですが、スレッドのように、同じコードの場合、その下に日付順でソートしたいです。 # 言っていることが、よくわからなくてすみません。 # # 元テーブル # DATE, CODE, VALUE # .... # 20140401, 11, A # 20140402, 12, B # 20140403, 11, C # 20140404, 13, D # 20140405, 12, E # 20140406, 11, F # .... # # 欲しい結果 # 20140401, 11, A # 20140403, 11, C # 20140406, 11, F # 20140402, 12, B # 20140405, 12, E # 20140404, 13, D # # 宜しくお願い致します。 # # # 879 名前:NAME IS NULL [sage]: 2014/04/25(金) 17:41:21.67 ID:??? # >>877 # どうも質問が明確じゃないけど、 # insert into tname select 〜 # の形式にすればとりあえず解決しそうな話に見える。 # # >>878 # order by code, date ということ? # # # 880 名前:NAME IS NULL []: 2014/04/25(金) 17:47:38.30 ID:+Fb19Efw (3) # 879 # 分かりずらい # 欲しい結果にしてしまいました。 # # 第1キーは、日付です。 # # 元テーブル # DATE, CODE, VALUE # 20140401, 13, A # 20140402, 11, B # 20140403, 12, C # 20140404, 13, D # 20140405, 12, E # 20140406, 11, F # # 欲しい結果 # 20140401, 13, A # 20140404, 13, D # 20140402, 11, B # 20140406, 11, F # 20140403, 12, C # 20140405, 12, E # # 宜しくお願い致します。 # # # 要するに第一キーは降順、第二キーは昇順で整列する。 # 'テーブルデータはDATE(YYYYMMの6けたのint型),CODE(varchar型),VALUE(varchar型) の3カラムからなります。各日付順の降順にしたいのですが、スレッドのように、同じコードの場合、その下に日付順でソートしたいです。'(_DATE,_CODE,_VALUE) :- '要するに第一キーは降順、第二キーは昇順で整列する。'(_DATE,_CODE,_VALUE). '要するに第一キーは降順、第二キーは昇順で整列する。'(_DATE,_CODE,_VALUE) :- 第一キー順序(_CODE), 第二キー順序(_CODE,_DATE), 元テーブル(_DATE,_CODE,_VALUE). 第一キー順序(_CODE) :- findsetof(_CODE,( 元テーブル(_DATE,_CODE,_VALUE)), L1), reverse(L1,L2), member(_CODE,L2). 第二キー順序(_CODE,_DATE) :- findsetof(_DATE,( 元テーブル(_DATE,_CODE,_VALUE)), L1), member(_DATE,L1). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1343899481/598 # # mysql 5.5 # # テーブル master # tcode # tname # lastdate # 〜 # # daily_data # select tcode,max(tdate) as maxdate # from daily_date # group by tcode; # # このdaily_dateから得られるmaxdateを使って # masterのtcodeの対応するlastdateに入れたいのですが、 # どのようにupdateを書けば良いのでしょうか? # 'daily_dateから得られるmaxdateを使ってmasterのtcodeの対応するlastdateに入れたい' :- dail_dateテーブルの構造(P1,_daily_date_tcode,_date), masterテーブルの構造(P2,_master_tcode,_lastdate), findsetof(_tcode,P1,L1), 最大日付に変更する(L1,P1,P2,_daily_date_tcode,_date,_master_tcode,_lastdate),!. daily_dateテーブルの構造(P,_tcode,_date) :- count(テーブル定義(daily_date,_,_),_アリティ), length(L,_アリティ), P =.. [daily_date|L], tcodeとdateの列位置を確定する(L,_tcode,_date),!. tcodeとdateの列位置を確定する(L,_tcode,_date),!. テーブル定義(daily_date,_nth1_tcode,tcode), テーブル定義(daily_date,_nth1_date,date), nth1(_nth1_tcode,L,_tcode), nth1(_nth1_date,L,_date),!. masterテーブルの構造(P,_tcode,_date) :- count(テーブル定義(master,_,_),_アリティ), length(L,_アリティ), P =.. [master|L], tcodeとlastdateの列位置を確定する(L,_tcode,_lastdate),!. tcodeとlastdateの列位置を確定する(L,_tcode,_date),!. テーブル定義(master,_nth1_tcode,tcode), テーブル定義(master,_nth1_lastdate,lastdate), nth1(_nth1_tcode,L,_tcode), nth1(_nth1_date,L,_lastdate),!. 最大日付に変更する(L1,P1,P2,_daily_date_tcode,_date,_master_tcode,_lastdate) :- forall(( member(_tcode,L1), findmax(_date,P1,_maxdate), lastdateの更新(_maxdate,P2,_tcode,_lastdate)), true). lastdateの更新(_maxdate,P,_tcode,_lastdate) :- retract(P), _lastdate = _maxdate, asserta(P),!. lastdateの更新(_maxdate,P,_tcode,_lastdate) :- _lastdate = _maxdate, asserta(P),!. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/816 # # table1 # id | name # ----------- # 0 | りんご # 1 | みかん # # table2 # no | id # ---------- # 0 | 0 # 1 | 0 # 2 | 1 # 3 | 1 # 4 | 1 # # この二つのテーブルから以下の結果を得るSQLの書き方を教えてください # id | name | num # ------------------- # 0 | りんご | 2 # 1 | みかん | 3 # # select id, name, (select count(code) from table2 as t2, table1 as t1 where t1.id=t2.code) as num from table1; # 自分で考えた↑では2行ともnumが5になってしまいました # # SELECT id, COUNT(id) # FROM table2 # GROUP BY id # # の結果と table1 を結合 # table1(0,りんご). table1(1,みかん). table2(0,0). table2(1,0). table2(2,1). table2(3,1). table2(4,1). 'table2をidで集約したテーブルにtable1を結合する'(_id,_name,_度数) :- setof(_id,[_no,_id] ^ ( table2(_no,_id)),_idならび), member(_id,_idならび), count(table2(_,_id),_度数), table1(_id,_name). % findsetof/3 % count/2 % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/tech/1337692704/48 # # 【課題】売り上げをコード事に個別に集計した後に全体の合計を出しなさい。 #    <エリアコード> <県コード> <地区コード> #     A \5000 C \4000 E \7000 # A \90000 C \6500 E \8000 # A \7500 C \5500 E \4000 # A \6000 C \3000 F \2000 # A \3500 C \9000 F \6500 # A \4200 C \4500 F \3000 # A \3500 D \8000 E \3000 # A \40000 D \9500 E \4880 # B \3500 C \8000 E \4500 # B \4200 C \9500 E \5000 # # 【形態】javaアプリケーション # 【期限】6/12 お昼 # 【Ver 】java version "1.7.0_02" # 【補足】キーブレイクの処理の参考書がなくて進みません。 # ACEから切り替わるときに<E地区合計> # ACFから切り替わるときに<F地区合計><C県合計> # ADEから切り替わるときに<E地区合計><D県合計><Aエリア合計> # BCEの後に       <E地区合計><C県合計><Bエリア合計> # 最後に<A+Bエリア合計>を出力する形でお願いします。 # # 売り上げ('A',5000,'C',4000,'E',7000). 売り上げ('A',90000'C',6500','E',8000). 売り上げ('A',7500,'C',5500,'E',4000). 売り上げ('A',6000,'C',3000,'F',2000). 売り上げ('A',3500,'C',9000,'F',6500). 売り上げ('A',4200,'C',4500,'F',3000). 売り上げ('A',3500,'D',8000,'E',3000), 売り上げ('A',40000,'D',9500,'E',4880). 売り上げ('B',3500,'C',8000,'E',4500). 売り上げ('B',4200,'C',9500,'E',5000). 'エリアコード鍵'(_鍵ならび) :- findsetof(_エリアコード,( 売り上げ(_エリアコード,_,_,_,_,_)), _鍵ならび). 'エリアコード・県コード鍵'(_鍵ならび) :- findsetof([_エリアコード,_県コード],( 売り上げ(_エリアコード,_,_県コード,_,_,_)), _鍵ならび). 'エリアコード・県コード・地区コード鍵'(_鍵ならび) :- findsetof([_エリアコード,_県コード,_地区コード],( 売り上げ(_エリアコード,_,_県コード,_,_地区コード,_)), _鍵ならび). 売り上げを表示する :- 'エリアコード鍵'(_鍵ならび_1), 'エリアコード・県コード鍵'(_鍵ならび_2), 'エリアコード・県コード・地区コード鍵'(_鍵ならび_3), 売り上げ集約を表示する(_鍵ならび_1,_鍵ならび_2,_鍵ならび_3). 売り上げ集約を表示する([],_鍵ならび_2,_鍵ならび_3) :- findsum(_金額_1,( 売り上げ(_,_金額_1,_,_,_,_)), 合計金額), writef('全エリア合計 %t 円\n',[_合計金額]),!. 売り上げ集約を表示する([_エリア鍵|R1],_鍵ならび_2,_鍵ならび_3) :- エリアで分類する(_エリア鍵,_鍵ならび_2,_鍵ならび_3), 売り上げを表示する(R1,_鍵ならび_2,_鍵ならび_3). エリアで分類する(_エリア鍵,[],_) :- findsum(_金額_1,( 売り上げ(_エリア鍵,_金額_1,_,_,_,_)), _合計金額), writef('%tエリア合計 %t 円\n',[_エリア鍵,_合計金額]),!. エリアで分類する(_エリア鍵,[[_エリア鍵,_県鍵]|R2],_鍵ならび_3) :- 県で分類する(_エリア鍵,_県鍵,_鍵ならび_3), エリアで分類する(_エリア鍵,R2,_鍵ならび_3). 県で分類する(_エリア鍵,_県鍵,[]) :- findsum(_金額_2,( 売り上げ(_エリア鍵,_1,_県鍵,_金額_2,_,_3)), _合計金額), writef('%t県合計 %t 円\n',[_県鍵,_合計金額]),!. 県で分類する(_エリア鍵,_県鍵,[[_エリア鍵,_県鍵,_地区鍵]|R3]) :- findsum(_金額_3,( 売り上げ(_エリア鍵,_1,_県鍵,_2,_地区鍵,_金額_3)), _合計金額), writef(\n'%t%t合計 %t 円 ',[_地区鍵,地区,_合計金額]), 県で分類する(_エリア鍵,_県鍵,R3). 県で分類する(_エリア鍵,_県鍵,[_|R3]) :- 県で分類する(_エリア鍵,_県鍵,R3). % 以下のサイトは # I have a database looks like; # # airport(ist, 90). # airport(saw, 45). # airport(esb, 60). # airport(adb, 60). # airport(erz, 30). # airport(ayt, 90). # airport(mlx, 30). # airport(tzx, 30). # # airplane(f1, ist, [esb,tzx,saw]). # airplane(f2, ist, [mlx,esb,erz,esb]). # airplane(f3, ist, [esb,ist,esb,ist]). # airplane(f4, saw, [ayt,saw,ayt,saw]). # airplane(f5, erz, [esb,erz,esb]). # airplane(f6, mlx, [ist,esb,tzx,saw]). # and I have a predicate called "testing" takes two lists as parameter. So, if you write testing([ist],X). you should get X=[esb,mlx]. I wrote this code. # # testing([],[]). # # testing([D|D1],[L|L1]) :- # airport(D,_), # airplane(_,D,[L|_]), # testing(D1,L1). # This works and the output is: # # [8] 60 ?- listConnections([ist],X). # X = [esb] ; # X = [mlx] ; # X = [esb]. # But this is not that I want. So the first problem is I need a single line answer like X=[esb,mlx]. The second problem is there shouldn't duplicate elements in the list. I hope my problem is clear. Any help would be greatly appreciated # airport(ist, 90). airport(saw, 45). airport(esb, 60). airport(adb, 60). airport(erz, 30). airport(ayt, 90). airport(mlx, 30). airport(tzx, 30). airplane(f1, ist, [esb,tzx,saw]). airplane(f2, ist, [mlx,esb,erz,esb]). airplane(f3, ist, [esb,ist,esb,ist]). airplane(f4, saw, [ayt,saw,ayt,saw]). airplane(f5, erz, [esb,erz,esb]). airplane(f6, mlx, [ist,esb,tzx,saw]). testing([],[]). testing([_airport|R1],[L|R2]) :- findsetof(_airport_1,( airport(_airport,_), airplane(_,_airport,[_airport_1|_])), L), testing(R1,R2). findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/662 # # MySQL5 # # 開始日、終了日を持ったテーブルを日付単位に表示したいです。 # tbl_job は、以下の構造です。 # # id, name, start_date, end_date # --------------------------- # 1, JOB1, 2012-04-01, 2012-04-03 # 2, JOB2, 2012-04-02, 2012-04-04 # # 上記テーブルから以下のように日付単位でJOBを表示するSQLを教えてほしいです。 # # date, id, name # -------------------- # 2012-04-01, 1, JOB1 # 2012-04-02, 1, JOB1 # 2012-04-02, 2, JOB2 # 2012-04-03, 1, JOB1 # 2012-04-03, 2, JOB2 # 2012-04-04, 2, JOB2 # # '開始日、終了日を持ったテーブルを日付単位に表示したい' :- 日付単位tbl_jobの生成(_日付単位tbl_jobならび), findsetof(_日付,( member([_date,_,_],_日付単位tbl_jobならび)), _日付ならび), 日付単位に表示する(_日付ならび,_日付単位tbl_jobならび). 日付単位tbl_jobの生成(_日付単位tbl_jobならび) :- findall(_日付,( tbl_job(_id,_name,_start_date,_end_date), 日付の生成(_start_date,_end_date,_日付)), _日付単位tbl_jobならび). 日付の生成(_終了年-_終了月-_終了日,_終了年-_終了月-_終了日,_終了年-_終了月-_終了日) :- !. 日付の生成(_開始年-_開始月-_開始日,_終了年-_終了月-_終了日,_開始年-_開始月-_開始日). 日付の生成(_開始年-_開始月-_開始日,_終了年-_終了月-_終了日,_年-_月-_日) :- 翌日(_開始年,_開始月,_開始日,_翌日年,_翌日月,_翌日日), 日付の生成(_翌日年-_翌日月-_翌日日,_終了年-_終了月-_終了日,_年-_月-_日). 翌日(_年,12,31,_翌年,1,1) :- !. 翌日(_年,_月,30,_年,_翌月,1) :- member(_月,[4,6,9,11]), _翌月 is _月 + 1,!. 翌日(_年,_月,31,_年,_翌月,1) :- _翌月 is _月 + 1,!. 翌日(_年,2,29,_年,3,1) :- !. 翌日(_年,2,28,_年,3,1) :- \+(うるう年(_年)), 翌日(_年,_月,_日,_年,_月,_翌日) :- _翌日 is _日 + 1. うるう年(_年) :- 0 is _年 mod 400,!. うるう年(_年) :- 0 is _年 mod 100,!, fail. うるう年(_年) :- 0 is _年 mod 4,!. うるう年(_年) :- \+(0 is _年 mod 4), fail. 日付単位に表示する(_日付ならび,_日付単位tbl_jobならび) :- member(_日付,_日付ならび), member([_日付,_id,_name],_日付単位tbl_jobならび), 日付の形式を整えながら一行表示する(_日付,_id,_name), fail. 日付単位に表示する(_日付ならび,_日付単位tbl_jobならび). 日付の形式を整えながら一行表示する(_年-_月-_日,_id,_name) :- swritef(S,'%2r-%2r-%2r',[_年-_月-_日]), 空白を0に置換した日付文字列(S,_空白を0に置換した日付文字列), writef('%t, %t, %t\n',[_空白を0に置換した日付文字列,_id,_name). 空白を0に置換した日付文字列(S,_空白を0に置換した日付文字列) :- findall(_文字_2,( sub_atom(S,_,1,_,_文字), 空白を0に置換(_文字,_文字_2)), _空白を0に置換した日付文字列). 空白を0に置換(' ','0') :- !. 空白を0に置換(A,A). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/649 # # SQLというよりテーブル設計の質問なんですがいいでしょうか? # # ユーザごとの日々変化するデータを1日1レコードずつ保存するために # 以下のようなテーブル構造を考えました。 # # USERSテーブル #  user_no (ユーザ番号 PK) #  latest_gen_no (最新世代番号) #  氏名その他の属性 # # RECORDSテーブル #  user_no (ユーザ番号 PK*) #  gen_no (世代番号 PK*) #  日々変化する値 # *user_no, gen_no のペアでPK # # GENERATIONSテーブル #  gen_no (世代番号 PK) #  date (日時) # # 全ユーザの最新世代の値を取得するべく、 # select ... from users u, records r # where u.user_no=r.user_no and u.latest_gen_no=r.gen_no; # というSQLを発行すると、ものすごく時間が掛かります。 # # PKやインデックスの設定の仕方に問題があるのでしょうか? # そもそもテーブルの構成がまずいでしょうか? # テーブル副目標(_テーブル名,_引数ならび,_属性名ならび,_副目標) :- findall(_,テーブル定義(_テーブル名,_,_属性名),_引数ならび), findall(_属性名,テーブル定義(_テーブル名,_,_属性名),_属性名ならび), _副目標 =.. [_テーブル名|_引数ならび]. 'USERSテーブルを最新世代に更新する' :- ユーザごとの現在の最新世代を得る(_ユーザごとの最新世代ならび), 'USERSテーブルを更新する'(_ユーザごとの最新世代ならび). ユーザごとの現在の最新世代を得る(_ユーザごとの最新世代ならび) :- 'テーブル副目標'('USERS',[_ユーザ番号,_最新世代番号|_氏名その他の属性],_,_USERS), findsetof(_ユーザ番号,( _USERS), _対象ユーザ番号ならび), ユーザごとの現在の最新世代を得る(_対象ユーザ番号ならび,_ユーザごとの最新世代ならび). ユーザごとの現在の最新世代を得る([],[]). ユーザごとの現在の最新世代を得る([_ユーザ番号|R1],[[_ユーザ番号,_最新世代番号]|R2]) :- テーブル副目標('RECORDS',[_ユーザ番号,_世代番号|_],_,_RECORDS), findmax([_日時,_世代番号],( _RECORDS, 'GENERATIONS'(_世代番号,_日時)), [_,_最新世代番号]), ユーザごとの現在の最新世代を得る(R1,R2). 'USERSテーブルを更新する'([]). 'USERSテーブルを更新する'([[_ユーザ番号,_最新世代番号]|R]) :- テーブル副目標('USERS',[_ユーザ番号,_|_氏名その他の属性],_,_USERS_1), テーブル副目標('USERS',[_ユーザ番号,_最新世代番号|_氏名その他の属性],_,_USERS_2), retract(_USERS_1), assertz(_USERS_2), 'USERSテーブルを更新する'(R),!. % 以下のサイトは # # 売上('20120416',トマト,3000). # 売上('20120417',ナス,1000). # 売上('20120416',トマト,1500). # 売上('20120417',ナス,2200). # # の時に、日付ごとの合計売上が欲しい。 # # ?- 集約加算(_集約値,[_日付,_集約値],[_日付],[_金額],売上(_日付,_品目,_金額),_解). # # _解 = [['20120416',4500],['20120417',3200]] # 集約加算(_集約解変数指定,_選択項,_鍵項,_集約項,P,_解) :- findsetof(_鍵項,P,L1), findkeysort(_選択項,_鍵項,( member(_鍵項,L1), findsum(_集約項,P,_集約解変数指定)), _解_1), 集約加算の解を平坦化する(_解_1,_解). 集約加算の解を平坦化する(_解_1,_解) :- findall(L3,( member(L2,_解_1), 平坦化(L2,L3)), _解) . %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). findkeysort(Select,Keys,P,List) :- append(Keys,Select,Keys2), findall(Keys2,P,List1), sort(List1,List2), findall(Select,member(Keys2,List2),List). 平坦化(_深いならび,_平坦化されたならび) :- 差分ならびによる平坦化(_深いならび,_平坦化されたならび - []) . 差分ならびによる平坦化([_項|_残りならび],_差分ならび頭部 - _差分ならび尾部) :- 差分ならびによる平坦化(_項,_差分ならび頭部 - _不完全な差分ならび), 差分ならびによる平坦化(_残りならび,_不完全な差分ならび - _差分ならび尾部) . 差分ならびによる平坦化([],_差分ならび頭部 - _差分ならび尾部) :- _差分ならび頭部 = _差分ならび尾部 . 差分ならびによる平坦化(_項,[_項|_差分ならび尾部] - _差分ならび尾部) :- \+(list(_項)),!. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/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; # # '日付を指定して、その日の商品別販売金額合計を大きい順に表示したい' :- '日付を指定して、'(_日付), その日の商品別販売金額合計を(_日付,L1), 大きい順に表示する(L1). '日付を指定して、'(_日付) :- write('日付を8桁の整数で入力して下さい : '), get_line(Line), '日付を指定して、の診断'(Line,_日付),!. '日付を指定して、'(_日付) :- '日付を指定して、'(_日付). '日付を指定して、の診断'(Line,_日付) :- atom_to_term(Line,_8桁の整数,_), '8桁の整数'(_8桁の整数), '8桁の整数から日付を得る'(_8桁の整数,_日付),!. '日付を指定して、の診断'(Line,_日付) :- writef('入力された %t からは日付が得られませんでした。再入力をお願いします\n',[Line]), 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([_年,'-',_月,'-',_日],_日付),!. その日の商品別販売金額合計を(_日付,L1) :- findsetof(_id,( sales(_id,_item_id,_count,_total,_日付)), L), findall([_total,_id],( append(_,[_id|R],L), 商品の販売合計(_日付,_id,_合計金額)), L1). 商品の販売合計(_日付,_id,_合計金額) :- findsum(_total,( sales(_id,_item_id,_count,_total,_日付)), _合計金額). 大きい順に表示する(L1) :- 大きい順に(L1,L2), 表示する(L2). 大きい順に(L1,L2) :- sort(L1,L3), reverse(L3,L2). 表示する(_日付,[]). 表示する(_日付,[[_合計金額,_id]|R]) :- items(_id,_name,_price), writef('%t %t %20l %10r\n',[_日付,_id,_name,_合計金額]), 表示する(_日付,R). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/633 # # MySQL 5.1です。 # # create table staff_list( # staff_id int(5) primary key //社員番号 # staff_name varchar(8) //社員名 # unit varchar(8) primary key //部署名 # ) # # insert into staff_list (staff_id,staff_name,unit) values # (1,'範馬','総務'), # (2,'愚地','総務'), # (3,'花山','総務'), # (1,'高津','企画'), # (2,'池谷','企画'), # (3,'長嶋','企画'), # (1,'鳩山','営業'), # (2,'野田','営業'), # (3,'小沢','営業'), # (4,'枝野','営業') # # # # このようなテーブルに対してSELECTをかける際、一度のクエリーで # 部署別にソートしたうえで、総務だけstaff_id降順で他を昇順で出したいと思っています。 # # order by unit,IF(staff_name='総務',staff_id desc,staff_id asc) # などと試行してみているのですがうまくできません。 # # どなたかうまい方法をご存じないでしょうか。 # # よろしくお願いいたします。 # スタッフリスト(1,範馬,総務). スタッフリスト(2,愚地,総務). スタッフリスト(3,花山,総務). スタッフリスト(1,高津,企画). スタッフリスト(2,池谷,企画). スタッフリスト(3,長嶋,企画). スタッフリスト(1,鳩山,営業). スタッフリスト(2,野田,営業). スタッフリスト(3,小沢,営業). スタッフリスト(4,枝野,営業). 'このようなテーブルを選択する際、一度部署別にソートしたうえで、総務だけ社員番号降順で出したいと思っています。'(_部署名,_社員番号,_社員名) :- 一度部署別にソートしたうえで(_部署名ならび), 総務だけ社員番号降順で出したい(_部署名ならび,_部署名,_社員番号,_社員名). 一度部署別にソートしたうえで(_部署名ならび) :- findsetof(_部署名,( スタッフリスト(_社員番号,_社員名,_部署名)), _部署名ならび). 総務だけ社員番号降順で出したい(_部署名ならび,_部署名,_社員番号,_社員名) :- member(_部署名,_部署名ならび), 総務だけ社員番号降順で出したい(_部署名,_社員番号,_社員名). 総務だけ社員番号降順で出したい(総務,_社員番号,_社員名) :- 総務だけ社員番号降順で(_社員番号,_社員名). 総務だけ社員番号降順で出したい(_部署名,_社員番号,_社員名) :- \+(_部署名 == 総務), スタッフリスト(_社員番号,_社員名,_部署名). 総務だけ社員番号降順で(_社員番号,_社員名) :- findall([_社員番号,_社員名],( スタッフリスト(_社員番号,_社員名,総務)), L1), 降順でソート(L1,L2), member([社員番号,_社員名],L2). 降順でソート(L1,L2) :- sort(L1,L3), reverse(L3,L2). % % findsetof/3 % % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/621 # # ■DBMS名とバージョン # MySQL 5.0 # # ■テーブルデータ # 店舗テーブル # AreaID      int(1)←この2つでキーになってます # TenpoID     int(1)←この2つでキーになってます # uriage       int(16) # # 社員テーブル # SyainNo      int(255) # AreaID       int(1) # TenpoID      int(1) # SyainName    varchar(256) # # ■欲しい結果 # # uriageが5000以下の店舗に属してる社員を抜き出す # のと # その社員をいっぺんに消す # # どのようにSQL文を書けばいいでしょうか? # % % この問題のように、findall/3を使って、単位節データベースから読み取る場合は % 単純にappend/3を使って解を組み上げていくのがよい。 % 'uriageが5000以下の店舗に属してる社員を抜き出す'(_uriageが5000以下の店舗に属してる社員Noと社員名ならび) :- 'uriageが5000以下の店舗'(_uriageが5000以下の店舗ならび), 'uriageが5000以下の店舗に属してる社員を抜き出す'(_uriageが5000以下の店舗,_uriageが5000以下の店舗に属してる社員Noと社員名ならび). 'uriageが5000以下の店舗に属してる社員を抜き出す'([],[]). 'uriageが5000以下の店舗に属してる社員を抜き出す'([[_AreaID,_TempoID]|R1],_uriageが5000以下の店舗に属してる社員Noと社員名ならび) :- 店舗に属してる社員(_AreaID,_TempoID,_店舗に属してる社員Noと社員名ならび), 'uriageが5000以下の店舗に属してる社員を抜き出す'(R1,_uriageが5000以下の店舗に属してる社員Noと社員名ならび_1), append(_店舗に属してる社員Noと社員名ならび,_uriageが5000以下の店舗に属してる社員Noと社員名ならび_1,_uriageが5000以下の店舗に属してる社員Noと社員名ならび). 'uriageが5000以下の店舗'(_uriageが5000以下の店舗ならび) :- findsetof([_AreaID,_TempoID],( 店舗(_AreaID,_TempoID,_uriage), _uriage =< 5000), _uriageが5000以下の店舗ならび). 店舗に属してる社員(_AreaID,_TempID,_店舗に属してる社員Noと社員名ならび) :- findall([_SyainNo,_SyainName],( 社員(_SyainNo,_AreaID,_TempoID,_SyainName)), _店舗に属してる社員Noと社員名ならび). 'uriageが5000以下の店舗に属してる社員を抜き出した上、その社員をいっぺんに消す' :- 'uriageが5000以下の店舗に属してる社員を抜き出す'(_uriageが5000以下の店舗に属してる社員Noと社員名ならび), append(_,[[_SyainNo,_SyainName]|R],_uriageが5000以下の店舗に属してる社員Noと社員名ならび), retract(社員(_SyainNo,_AreaID,_TempoID,_SyainName)), R = []. % findsetof/3 % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/614 # # ・DBMS名とバージョン # MySQL # # ・テーブルデータ # 店舗(店舗ID 店舗名) # # 商品(商品ID 店舗ID 商品名) # (※同じ名前の商品が複数の店舗にあっても、別の商品として扱う) # # 売り上げ(売り上げID 商品ID 個数) # # ・欲しい結果 # 店舗名 商品名 売り上げ個数合計 # (※店舗名、商品名でソート) # # ・説明 # SELECT * FROM `店舗` ORDER BY `店舗名`; # この結果をプログラム側でループ # SELECT * FROM 商品 WHERE 店舗ID=? ORDER BY `商品名`; # さらにこの結果をループ # SELECT SUM(個数) FROM 売り上げ WHERE 商品ID=? # # これだと時間がかかりすぎるので、これを1つ、または2つのSQLにまとめたいです。 # # # SELECT *, SUM(`売り上げ`.個数`) AS `売り上げ個数合計` # FROM `商品` # LEFT JOIN `売り上げ` ON `商品`.`商品ID` = `売り上げ`.`商品ID` # WHERE `商品`.`店舗ID`=? # # とりあえず下2つだけでもまとめようとしてみたのですが、合計が商品毎ではなく店舗毎の合計になってしまいます。 # # # '店舗名・商品名を鍵として売り上げ個数合計を集約する'(_店舗名,_商品名,_売り上げ個数合計) :- '店舗名・商品名を鍵ならびとする'(LL1), '店舗名・消費名を鍵に売り上げ個数合計を集約する'(LL1,LL2), member([_店舗名,_商品名,_売り上げ個数合計],LL2). '店舗名・商品名を鍵ならびとする'(LL1) :- findsetof([_店舗名,_商品名],( 店舗(_店舗ID,_店舗名), 商品(_商品ID,_店舗ID,_商品名)), LL1). '店舗名・消費名を鍵に売り上げ個数合計を集約する'(LL1,LL2) :- findall([_店舗名,_商品名,_売り上げ個数合計],( count((member([_店舗名,_商品名],LL1), 店舗(_店舗ID,_店舗名), 商品(_商品ID,_店舗ID,_商品名)),_売り上げ個数合計)), LL2). % findsetof/3 % count/2 % findsum/3 % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/569 # # code | val # ------------ # A | 11 # A | 23 # A | 34 # A | 42 # B | 321 # B | 112 # B | 23 # B | 245 # というようなテーブルがあり、ここから # 同じcodeを持つ行が4行以上ある場合、val順で小さい方から3行残してのこりを削除 # したいのですが、SQL一発でできますか?DBMSはMySQLです。 # # ↓ほしい結果 # code | val # ------------ # A | 11 # A | 23 # A | 34 # B | 112 # B | 23 # B | 245 # # '同じcodeを持つ行が4行以上ある場合、val順で小さい方から3行残してのこりを削除したい' :- findsetof(_code,( table(_code,_)), _code候補ならび), append(_,[_code|R],_code候補ならび), 'code毎にvalの小さい順4位以下の組を'(_code,_4位以下の組ならび), '削除する'(_4位以下の組ならび), R = []. 'code毎にvalの小さい順4位以下の組を'(_code,_4位以下の組ならび) :- findall([_val,_code],( table(_code,_val)), L1), sort(L1,L2), 'valの小さい順4位以下の組'(L2,_4位以下の組ならび). 'valの小さい順4位以下の組'([_,_,_|R],R) :- !. 'valの小さい順4位以下の組'(_,[]). 削除する([]). 削除する([[A,B]|R]) :- retract(table(B,A)), 削除する(R). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/569 # # code | val # ------------ # A | 11 # A | 23 # A | 34 # A | 42 # B | 321 # B | 112 # B | 23 # B | 245 # というようなテーブルがあり、ここから # 同じcodeを持つ行が4行以上ある場合、val順で小さい方から3行残してのこりを削除 # したいのですが、SQL一発でできますか?DBMSはMySQLです。 # # ↓ほしい結果 # code | val # ------------ # A | 11 # A | 23 # A | 34 # B | 112 # B | 23 # B | 245 # # '同じcodeを持つ行が4行以上ある場合、val順で小さい方から3行残してのこりを削除したい' :- findsetof(_code,( table(_code,_)), _code候補ならび), append(_,[_code|R],_code候補ならび), 'code毎にvalの小さい順最大3件'(_code,L), '最大3件を書き戻す'(L), R = []. 'code毎にvalの小さい順最大3件'(_code,L) :- findall([_val,_code],( retract(table(_code,_val))), L1), sort(L1,L2), 'valの小さい順最大3件'(L1,L). 'valの小さい順最大3件'([],[]). 'valの小さい順最大3件'([[A1,B1],[A2,B2],[A3,B3]|_],[[B1,A1],[B2,A2],[B3,A3]]) :- !. 'valの小さい順最大3件'([[A,B]|R1],[[B,A]|R2]) :- 'valの小さい順最大3件'(R1,R2). '最大3件を書き戻す'([]). '最大3件を書き戻す'([[A,B]|R]) :- assertz(table(A,B)), '最大3件を書き戻す'(R). % 以下のサイトは # # データセット # date # 2001-10-19 # 2001-10-19 # 2003-12-7 # 2004-9-7 # .... # # といったidと日付の集まりがあります。日付は重複しています。 # ここから,SELECT count(date) FROM table GROUP BY dateで日付ごとの集計が # とれたのですが、さらにmaxを使って集計が最大の日の日付とカウント数を # 出したいのですがうまくいきません。 # 上の例では、2001-10-19,2というのを取りたいのですが、どうやったらいいんでしょうか? '集計が最大の日の日付とカウント数'(_日付,_度数) :- findsetof(_日付,( データセット(_日付)), _日付ならび), member(_日付,_日付ならび), count(データセット(_日付),_度数). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/411 # # 質問です。DBはSQLite3です。 # 構成が同じなので../test/read.cgi/db/1316769778/244のテーブルを説明に使わせてもらいます # # shop # id name # 1 Aカンパニー # 2 Bカンパニー # 3 Cカンパニー # # area # 1 北海道 # 2 青森 # 3 岩手 # 4 秋田 # # shop_area # shop_id area_id # 1 1 # 1 2 # 1 3 # 2 2 # 2 4 # 3 2 # 3 3 # # # 北海道なら、Bカンパニー・Cカンパニー # 青森なら、無し # 岩手なら、Bカンパニー # 秋田なら、Aカンパニー・Cカンパニー # 北海道・秋田なら、Cカンパニー # # 除外検索の要領で、対象の支社が無い会社を呼び出したい時はどうすればよいのでしょうか # '除外検索の要領で、対象の支社が無い会社を呼び出す' :- '除外検索の要領で、対象の支社が無い会社を呼び出す'(_地域ならび,_対象の支社が無い会社ならび), concat_atom(_地域ならび,'・',S1), concat_atom(_対象の支社が無い会社ならび,'・',S2), writef('%tなら、%t\n',[S1,S2]), fail. '除外検索の要領で、対象の支社が無い会社を呼び出す'. '除外検索の要領で、対象の支社が無い会社を呼び出す'(_地域ならび,_対象の支社が無い会社ならび) :- findall([_area_name,_対象の支社が無い会社ならび],( '対象の支社が無い会社を呼び出す'(_area_name,_対象の支社が無い会社ならび)), L1), findsetof(_対象の支社が無い会社ならび,( append(_,[[_,_対象の支社が無い会社ならび]|_],L1)), _対象の支社が無い会社ならびパターン), append(_,[_対象の支社が無い会社ならび|_],_対象の支社が無い会社ならびパターン), findall(_area_name,( append(_,[[_area_name,_対象の支社が無い会社ならび]|_],L1)), _地域ならび). '対象の支社が無い会社を呼び出す'(_area_name,_対象の支社が無い会社ならび) :- area(_area_id,_area_name), findsetof([_shop_id,_name],( shop_area(_shop_id,_area_id), shop(_shop_id,_name)), L1), findall(_name,( append(_,[[_shop_id,_name]|_],L1), \+(shop_area(_shop_id,_area_id))), _対象の支社が無い会社ならび). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/365 # # ・DB名:Firebird1.03 # ・テーブル #  ■メイン #   受注番号 受注日 注文社 #   11    2011/12/20 A社 #   12    2011/12/21 B社 #  ■サブ #   連番 受注番号 商品コード 数 #   50  11    A10    100 #   51  11    C30    20 #   52  12    A10    10 #  ■商品 #   商品コード 商品名 カテゴリ 納品番号(商品ごとで重複していません) #   A10     コート 洋服   100 #   C30     帯   和服   504 # # メインの受注番号とサブの受注番号、サブの商品コードと商品の商品コードで # リンクしています。 # # 欲しい結果 # 受注日の期間(いつからいつまで)と、商品のカテゴリと納品番号で、 # 受注の全内容(商品)が知りたいです。 # 受注日:2011/12/01から12/31まで # カテゴリ:洋服 納品番号:100で検索をして # # 受注番号 受注日 注文者 商品コード 商品名 数量 # 11    2011/12/20 A社 A10    コート 100 # 11    2011/12/20 A社 C30    帯   20----★ # 12    2011/12/21 B社 A10    コート 10 # ★受注の全内容が知りたいので、該当する受注番号のサブはすべて表示 # したい。メインの内容は重複表示となります。 # # 丸投げですみませんが、どなたかSQL文をお願いできませんでしょうか。 # テーブルが3つになるとどうしてよいものかわからないです。 # よろしくお願いします。 # # # '受注日の期間(いつからいつまで)と、商品のカテゴリと納品番号で、受注の全内容(商品)が知りたい'(_受注日下限,_受注日上限,_商品カテゴリ,_納品番号) :- 受注番号候補を得る(_受注日下限,_受注日上限,_カテゴリ,_納品番号,_受注番号ならび), findall([_受注番号,_受注日,_注文者,_商品コード,_商品名,_数量],( append(_,[_受注番号|_],_受注番号ならび), 受注番号を鍵にデータベースからの選択(_受注番号,_受注日,_注文者,_商品コード,_商品名,_数量)), LL1), 整列(LL1,LL2), 表示する(LL2). 受注番号候補を得る(_受注日下限,_受注日上限,_カテゴリ,_納品番号,_受注番号ならび) :- findsetof(_受注番号,( メイン(_受注番号,_受注日,_注文社), _受注日 @>= _受注日下限, _受注日 @=< _受注日上限, サブ(_連番,_受注番号,_商品コード,_数量), 商品(_商品コード,_商品名,_カテゴリ,_納品番号)), _受注番号ならび). 受注番号を鍵にデータベースを結合(_受注番号,_受注日,_注文者,_商品コード,_商品名,_数量) :- メイン(_受注番号,_受注日,_注文社), サブ(_連番,_受注番号,_商品コード,_数量), 商品(_商品コード,_商品名,_カテゴリ,_納品番号). 表示する(LL) :- write('受注番号 受注日 注文者 商品コード 商品名 数量\n'), append(_,[[_受注番号,_受注日,_注文者,_商品コード,_商品名,_数量]|R],LL), writef('%10l %8l %8c %8c %8c %14l %8r\n',[_受注番号,_受注日,_注文者,_商品コード,_商品名,_数量]), R = []. % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/332 # # oracleです。 # # ・テーブルデータ # テーブルA #  ID |日付 #  100|10/1 #  100|10/2 # 100|10/5 #  101|11/1 #  102|11/1 #  102|11/2 #  103|12/1 # # # テーブルB #  ID |期間(自)|期間(至) #  100|10/1  |10/4 #  101|10/1  |10/30 #  102|11/1  |11/5 #  103|12/1  |12/1 #   # # ・欲しい結果 # #  ID |期間内のカウント #  100|2 #  101|0 #  102|2 #  103|1 #   # # ・説明: # IDをキーに、期間内のIDごとのカウントをとりたいです。 # SQL1本で取得する方法はありますでしょうか? # 列は増やしたくないです。 # テーブルA(100,10/1). テーブルA(100,10/2). テーブルA(100,10/5). テーブルA(101,11/1). テーブルA(102,11/1). テーブルA(102,11/2). テーブルA(103,12/1). テーブルB(100,10/1,10/4). テーブルB(101,10/1,10/30). テーブルB(102,11/1,11/5). テーブルB(103,12/1,12/1). 'IDをキーに、期間内のIDごとのカウントをとりたい'(_ID,_期間_自,_期間_至,_度数) :- findsetof([_ID,_期間_自,_期間_至],( テーブルB(_ID,_期間_自,_期間_至)), LL1), append(_,[[_ID,_期間_自,_期間_至]|_],LL1), count(( テーブルA(_ID,_日付), _日付 @>= _期間_自, _日付 @=< _期間_至), _度数). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/323 # # 【質問テンプレ】 # ・DBMS名とバージョン MySQL 5.1 # ・テーブルデータ # ・欲しい結果 # ・説明 # # テーブル「カート」 # カラム 「セッションID」「商品種別」「カートに入れた時刻」 # # テーブル「カート詳細」 # カラム 「セッションID」「商品コード」 # # テーブル「商品リスト」 # カラム「商品コード」「商品種別」 # # というテーブルがあります。 # # 最後にカートに入れた時刻から12時間以上経過したセッションIDを検索して、 # そのセッションIDを持つレコードを「カート」「カート詳細」の両方から # 全て削除したいのです。 # # 同じセッションIDを持つレコードは、両方のテーブルに複数あります。 # 「注文」テーブルで「セッションID」「商品種別」の組合せはユニークで、 # 「注文詳細」テーブルでは「セッションID」「商品コード」の組合せにユニークです。 # # 結合や副問い合わせを試してみましたが、うまいこと抽出できません。 # SQLで書くやり方があれば教えてください。よろしくお願いします。 # # '最後にカートに入れた時刻から12時間以上経過したセッションIDを検索して、そのセッションIDを持つレコードを「カート」「カート詳細」の両方から全て削除する' :- '最後にカートに入れた時刻から12時間以上経過したセッションIDを検索して'(_セッションID,R), 'そのセッションIDを持つレコードを「カート」「カート詳細」の両方から全て削除する'(_セッションID), R = []. '最後にカートに入れた時刻から12時間以上経過したセッションIDを検索して'(_セッションID,R) :- findsetof(_セッションID,( カート(_セッションID,_商品種別,_カートに入れた時刻)), _セッションIDならび), append(_,[_セッションID|R],_セッションIDならび), findmax(_カートに入れた時刻,( カート(_セッションID,_商品種別,_カートに入れた時刻)), _最後にカートに入れた時刻), 最後にカートに入れた時刻から12時間以上経過している(_セッションID,_最後にカートに入れた時刻). 'そのセッションIDを持つレコードを「カート」「カート詳細」の両方から全て削除する'(_セッションID) :- retractall(カート(_セッションID,_,_)), retractall(カート詳細(_セッションID,_)). 最後にカートに入れた時刻から12時間以上経過している(_セッションID,_最後にカートに入れた時刻) :- split(_最後に入れた時刻,['/',' ',':'],[_年,_月,_日,_時,_分]), 現在の時刻(_年_1,_月_1,_日_1,_時_1,_分_1), '12時間後の日時'(_年,_月,_日,_時,_分,_年_2,_月_2,_日_2,_時_2,_分_2), [_年_1,_月_1,_日_1,_時_1,_分_1] @>= [_年_2,_月_2,_日_2,_時_2,_分_2],!. '12時間後の日時'(_年,_月,_日,_時,_分,_年,_月,_日,_時_2,_分) :- _時_2 is _時 + 12, _時_2 < 24,!. '12時間後の日時'(_年,_月,_日,_時,_分,_年,_月,_日_2,_時_2,_分) :- _時_1 is _時 + 12, _時_2 is _時_1 - 24, _日_2 is _日 + 1,!. retractall(P) :- retract(P), fail. retractall(_). % 以下のサイトは # 出典:: http://toro.2ch.net/test/read.cgi/db/1316769778/319 # # tbl_rosen (駅名と備考は1:1) # 路線名  駅名  備考 # ---------------------- # A線   i駅   備考1 # A線   j駅   備考2 # A線   k駅   備考3 # B線   k駅   備考3 # B線   l駅   備考4 # B線   m駅   備考5 # C線   n駅   備考6 # D線   k駅   備考3 # D線   o駅   備考7 # # tbl_shop # 店名  最寄駅 # --------------- # X店   j駅 # X店   m駅 # X店   o駅 # Y店   l駅 # Z店   k駅 # # tbl_rosenは鉄道路線とその駅名のテーブル(1路線に対して1〜n駅ある)、 # tbl_shopは、スーパーの名前と最寄駅(1店に対して0〜nの最寄駅がある) # # <やりたいこと> # ・その店に鉄道で行くことが出来る駅のリストを作成したい # ・ある特定の路線は除外(上の例だと、D線は対象外) # ・乗り換えは考慮しない。 # # →例えば、Z店はk駅が最寄りで、k駅はA線、B線、D線の乗り入れ。D線を除外すると、 # i、j、k、l、m駅から電車(±徒歩)でZ店に行ける # # <最終的に出力したいテーブル) # tbl_output # 店名  最寄駅  備考 # ---------------------- # X店   i駅   備考1 # X店   j駅   備考2 # X店   k駅   備考3 # X店   l駅   備考4 # X店   m駅   備考5 # Y店   k駅   備考3 # Y店   l駅   備考4 # Y店   m駅   備考5 # Z店   i駅   備考1 # Z店   j駅   備考2 # Z店   k駅   備考3 # Z店   l駅   備考4 # Z店   m駅   備考5 # # # 2段階に分ければ(駅で結合して店名、路線名でグループ化(D線除外)した # テンポラリテーブルをつくって、さらにtbl_rosenと結合する)普通にできるのですが、 # 出来れば一発のSQLで出力したいのですが、SQL自体にまだ馴染みが薄く、 # どのように書いて良いのかわかりません # # よろしくお願いします(PostgreSQL8.4です) # # 'その店に鉄道で行くことが出来る駅のリストを作成したい ・ある特定の路線は除外(上の例だと、D線は対象外)・乗り換えは考慮しない。 '(_店名,_除外する路線名ならび,L) :- 店候補(_店名,R), その店に鉄道で行くことができる駅候補(_店名,_路線名ならび), その店に鉄道で行くことが出来る駅のリストを作成する(_店名,_除外する路線名ならび,_路線名ならび), R = []. 店候補(_店名,R) :- findsetof(_店名,( tbl_shop(_店名,_,_)), _店名ならび), append(_,[_店名|R],_店名ならび). その店に鉄道で行くことができる駅候補(_店名,_路線名ならび) :- findsetof(_路線名,( tbl_shop(_店名,_最寄駅,_備考1), tbl_rosen(_路線名,_最寄駅,_備考2)), _路線名ならび). その店に鉄道で行くことが出来る駅のリストを作成する(_店名,_除外する路線名ならび,_路線名ならび) :- append(_,[_路線名|R],_路線名ならび), tbl_rosen(_路線名,_駅名,_備考), \+((member(_路線名,_除外する路線名ならび)), assertz(tbl_output(_店名,_駅名,_備考)), R = []. findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). findsetof(A,B) :- findall(A,B,C), setof(A,member(A,C),D), member(A,D). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1316769778/293 # # oracleです。 # # ・テーブルデータ # テーブルA #  ID |状態 #  100|○ #  100|○ #  101|○ #  102|○ #  104|○ #  105|× # テーブルB #  ID |状態 #  100|○ #  100|○ #  100|○ #  103|○ #  105|○ #  106|× # # ・欲しい結果 # #  ID |AのCOUNT(ID)|BのCOUNT(ID) #  100|2 |3 #  101|1 |null #  102|1 |null #  104|1 |null #  105|null |1 # # ・説明: # A,B各テーブルの状態が○であるものをID単位でカウントし、 #  AとBのテーブルを結合したいのですが、SQL1本で可能でしょうか? #  結合する際、どちらかのテーブルのカウントが1以上であれば出力したいです。 # # 'A,B各テーブルの状態が○であるものをID単位でカウントし、AとBのテーブルを結合したいのですが、SQL1本で可能でしょうか? 結合する際、どちらかのテーブルのカウントが1以上であれば出力したいです。'(_ID,CountA,CountB) :- findsetof(_ID,( テーブルA(_ID,○ ); テーブルB(_ID,○ )), L), append(_,[_ID|_],L), count(テーブルA(_ID,○ ),CountA), count(テーブルB(_ID,○ ),CountB). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1320365280/822 # # [1] 授業単元:c言語プログラミング # [2] 問題文(含コード&リンク):(1,2,3) (1,2,4)...といった数列が続くのlist.txtを読み込み、 # 左の数字が同じかつ真ん中の数字も同じとき、右の数字が大きいものを削除し、link2.txtに書きこむプログラムを作りなさい。 # (この場合、左が1と1かつ真ん中が2と2で右が3と4なので4の方が大きいので(1,2,4)を削除する) # '(1,2,3) (1,2,4)...といった数列が続くのlist.txtを読み込み、左の数字が同じかつ真ん中の数字も同じとき、右の数字が大きいものを削除し、link2.txtに書きこむ' :- get_chars('list.txt',Chars), '左の数字が同じかつ真ん中の数字も同じとき、右の数字が大きいものを削除し、link2.txtに書きこむ'(Chars). '左の数字が同じかつ真ん中の数字も同じとき、右の数字が大きいものを削除し、link2.txtに書きこむ'(Chars) :- ならびに変換(Chars,LL1), '左の数字が同じかつ真ん中の数字も同じとき、右の数字が大きいものを削除し'(LL1,LL2), 'link2.txtに書きこむ'(LL2). ならびに変換([],[]). ならびに変換(['('|R1],[[A,B,C]|R2]) :- append(L0,[)|R3],R1), concat_atom(L0,S), atom_to_term(S,(A,B,C),_), ならびに変換(R3,R2),!. ならびに変換([_|R1],R2) :- ならびに変換(R1,R2). '左の数字が同じかつ真ん中の数字も同じとき、右の数字が大きいものを削除し'(LL1,LL2) :- 左の数字と真ん中の数字でグループを作る(LL1,LL3), グループの中の最小ならびを蒐める(LL3,LL2). 左の数字と真ん中の数字でグループを作る(LL1,LL3) :- findsetof([A,B],( append(_,[[A,B,_]|_],LL1)), LL3). グループの中の最小ならびを蒐める(LL3,LL2) :- findall(L,( グループの中での最小ならび(LL3,L)), LL2). グループの中での最小ならび(LL3,L) :- append(_,[[A,B]|_],LL3), findmin([A,B,C],( append(_,[[A,B,C]|_],LL1)), L). 'link2.txtに書きこむ'(LL2) :- open('link2.txt',write,Outstream), 'link2.txtに書きこむ'(Outstream,LL2), close(Outstream). 'link2.txtに書きこむ'(Outstream,LL2) :- append(_,[[A,B,C]|R],LL2), writef(Outstream,'(%t,%t,%t) ',[A,B,C]), R = [], 最後に改行(Outstream). 最後に改行(Outstream) :- write(Outstream,'\n'). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1316769778/249 # # ・MySQL5です # ・テーブルデータ #  ID|名前|データ #  01|鈴木|0001 #  02|佐藤|0002 #  01|鈴木|0003 # ・欲しい結果 #  ID|名前|*|DATA1|DATA2 #  01|鈴木|2|0001 |0003 #  02|佐藤|1|0002 | # # ・説明:group by と count(*) を使うと↓のように、グループ化され消えてしまう列の値を(この場合`0003`の部分)、↑みたく、行に書出す方法はありますか? #  ID|名前|*|データ #  01|鈴木|2|0001 #  02|佐藤|1|0002 # # ・補足:IDは1~1400、count数は1~97、DATAは1~4000位あります。 # # 欲しい結果(_組) :- 欲しい結果(_組,_). 欲しい結果(_組,_残り鍵ならび) :- 鍵ならびを作る(_鍵ならび), 鍵データの収集(_鍵ならび,_組,_残り鍵ならび). 欲しい結果の表示 :- 欲しい結果(_組,_残り鍵ならび), concat_atom(_組,'|',_組表示文字列), writef('%t\n',[_組表示文字列]), _残り鍵ならび = []. 鍵ならびを作る(_鍵ならび) :- findsetof([_ID,_名前],( テーブルデータ(_ID,_名前,_データ)), _鍵ならび). 鍵データの収集(_鍵ならび,_既に処理した鍵ならび,_組,_残り鍵ならび) :- 一つ鍵を取り出し(_鍵ならび,_既に処理した鍵ならび,_鍵,_残り鍵ならび), 鍵に対応するデータならび(_鍵,_鍵に対応するデータならび), 組の構成(_鍵,_鍵に対応するデータならび,_組). 一つ鍵を取り出し(_鍵ならび,_既に処理した鍵ならび,_鍵,_残り鍵ならび) :- append(_既に処理した鍵ならび,[_鍵|_残り鍵ならび],_鍵ならび). 鍵に対応するデータならび(_鍵,_鍵に対応するデータならび) :- _鍵 = [_ID,_名前], findall(_データ,( テーブルデータ(_ID,_名前,_データ)), _鍵に対応するデータならび). 組の構成(_鍵,_鍵に対応するデータならび,_組) :- length(_鍵に対応するデータならび,_度数), append(_鍵,[_度数|_鍵に対応するデータならび],_組). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1316769778/221 # # DBMSはMysqlの5.0.87です。 # # +------+------------+---------+----------+ # | id   | product_id | assy_id | parts_id | # +------+------------+---------+----------+ # |    1 |          1 |      12 |        1 | # |    2 |          1 |      12 |        2 | # |    3 |          1 |      12 |        3 | # |    4 |          1 |      12 |        3 | # |    5 |          1 |      12 |        5 | # +------+------------+---------+----------+ # # 上記のテーブルで、product_id、assy_id、parts_idが同じレコードが2行以上有るものを抽出したいのです。 # 上記の例だとidが3と4のレコードになります。 # # # '上記のテーブルで、product_id、assy_id、parts_idが同じレコードが2行以上有るものを抽出する'(_id) :- findsetof([_product_id,_assy_id,_parts_id],( テーブル(_id,_product_id,_assy_id,_parts_id)), LL), append(_,[[_product_id,_assy_id,_parts_id]|_],LL), count(テーブル(_,_product_id,_assy_id,_parts_id),Count), Count >= 2. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1316769778/136 # # SQLserverの質問です # # 以下のようなテーブルがあります # *はユニークキーです。 # # DATE* ID1* ID2* VALUE # _______________ # # 200103 AAA 111 20 # 200103 AAA 112 10 # 200103 AAA 113 55 # 200103 AAA 121 60 # 200103 AAA 122 54 # 200103 AAA 123 44 # 200103 BBB 111 24 # 200103 BBB 113 43 # 200103 BBB 114 11 # 200103 BBB 121 11 # ・ # ・ # ・ # 200104 AAA 111 20 # 200104 AAA 112 10 # 200104 AAA 114 5 # 200104 AAA 122 54 # 200104 AAA 123 4 # 200104 BBB 111 24 # 200104 BBB 113 43 # 200104 BBB 112 21 # 200104 BBB 121 11 # 200105 AAA 122 54 # 200105 BBB 113 43 # 200105 BBB 112 21 # 200106 AAA 123 4 # 200106 BBB 111 24 # 200106 BBB 112 21 # # これをDATE=200103とDATE=200104だけとってきて # いかのように外部結合したいのですがどのようにすればよいでしょうか? # FULL JOINを利用したのですがうまくいきません。 # # ID1 ID2 VALUE_201103 VALUE_201104 # _________________________________________ # AAA 111 20 20 # AAA 112 10 10 # AAA 113 55 NULL # AAA 114 NULL 5 # AAA 121 60 NULL # ・ # ・ # ・ # # よろしくお願いいたします。 # # '以下のようなテーブルがあります *はユニークキーです。 DATE* ID1* ID2* VALUE これをDATE=200103とDATE=200104だけとってきて外部結合する'(_ID1,_ID2,_VALUE_200103,_VALUE_200104) :- findsetof([_ID1,_ID2],( テーブル(_日付,_ID1,_ID2,_), '日付が200103か200104'(_日付)), LL1), append(_,[[_ID1,_ID2]|_],LL1), '日付が200103か200104の適合組'(_ID1,_ID2,_VALUE_200103,_VALUE_200104). '日付が200103か200104'('200103'). '日付が200103か200104'('200104'). '日付が200103か200104の適合組'(_ID1,_ID2,_VALUE_200103,_VALUE_200104) :- テーブル('200103',_ID1,_ID2,_VALUE_200103), テーブル('200104',_ID1,_ID2,_VALUE_200104),!. '日付が20103か200104の適合組'(_ID1,_ID2,'NULL',_VALUE_200104) :- \+(テーブル('200103',_ID1,_ID2,_)), テーブル('200104',_ID1,_ID2,_VALUE_200104),!. '日付が200103か200104の適合組'(_ID1,_ID2,_VALUE_200103,'NULL') :- テーブル('200103',_ID1,_ID2,_VALUE_2001003), \+(テーブル('200104',_ID1,_ID2,_)),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/890 # # 初心者ですが失礼いたします。 # ID | DATA | TIME # --+------ # 1 | aaa | 01:02 # 2 | bbb | 03:42 # 1 | ccc | 02:11 # 3 | bbb | 01:32 # # というデータがあるとしまして # タイムが早い順に並べ替えて重複するIDを除外(この場合は1) # するにはどのようなクエリを書けばよいのでしょうか? # # select * from table ORDER BY `time` DESC # でタイム順には並べることができていますが重複するID(人物) # を除外したいのです。 # # % findsetof/3 % findmin/3 % を参照してください。 'タイムが早い順に並べ替えて重複するIDを除外する'(_ID,_DATA,_TIME) :- findsetof(_ID,( テーブル(_ID,_DATA,_TIME)), L1), append(_,[_ID|_],L1), findmax([_TIME,_ID,_DATA],( テーブル(_ID,_DATA,_TIME)), [_TIME,_ID,_DATA]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/860 # # 09/01 りんご # 09/02 りんご # 09/02 みかん # 09/03 りんご # 09/03 みかん # 09/03 バナナ # ・・・ # # このようなテーブルからりんごとみかんとバナナの3つ # 全てがある日付を取り出す構文はどうすれば出来ますか? # # '09/01 りんご\n09/02 りんご\n09/02 みかん\n09/03 りんご\n09/03 みかん\n09/03 バナナ\n・・・ このようなテーブルからりんごとみかんとバナナの3つ全てがある日付を取り出す'(_日付) :- findsetof(_日付,( テーブル(_日付,_)), L1), 'りんごとみかんとバナナの3つ全てがある日付'(L1,_日付). 'りんごとみかんとバナナの3つ全てがある'([_日付|R],_日付) :- 'りんごとみかんとバナナの3つ全てがある'(_日付). 'りんごとみかんとバナナの3つ全てがある'([_|R],_日付) :- 'りんごとみかんとバナナの3つ全てがある'(R,_日付). 'りんごとみかんとバナナの3つ全てがある'(_日付) :- テーブル(_日付,りんご), テーブル(_日付,みかん), テーブル(_日付,バナナ),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/846 # # あるカラムの重複のみを外したものをSELECTするにはどうとればいいですか? # # kadenテーブル # id item price # 1 パソコン 100000 # 2 パソコン 80000 # 3 デジカメ 50000 # 4 プリンター 20000 # 5 デンワ 6000 # # 結果 # 1 パソコン 100000 # 3 デジカメ 50000 # 4 プリンター 20000 # 5 デンワ 6000 # # パソコンを区別するのはidとpriceがありますがidが若い方でお願いします # # 'あるカラムの重複のみを外したものをSELECTする' :- findsetof(_item,( kaden(_id,_item,_price)), L), append(_,[_item|_],L), 第一解のみ取得(_id,_item,_price). 第一解のみ取得(_id,_item,_price) :- kaden(_id,_item,_price),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/839 # # MySQLです。 # テーブルから最初コラムAで並びかえて、その中の上位30個を # コラムBで並び替えた結果がほしい時はどう書けばいいのでしょうか # # SELECT * FROMT T ORDER BY A,B # だと、Aの中の同じ値の物しかBでソートされないみたいです。 # # 'テーブルから最初コラムAで並びかえて、その中の上位30個をコラムBで並び替えた結果がほしい'(_A,_B) :- length(L0,30), findsetof([_A,_B],( 'T'(_A,_B)), L1), sort(L1,L2), append(L0,_,L2), findall([_B,_A],member([_A,_B],L0),L3), sort(L3,L4), member([_B,_A],L4). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/804 # # 以下のようなテーブルTABがあります。 # # A B C # 1 40 35 # 2 80 50 # 3 10 5 # 4 20 15 # 5 70 60 # # 列Aで昇順にソートして一番小さい値を持つ行を基準に、 # 以下の計算式で列Dを求めたいです。 # # D(n+1)= C(n)× D(n)÷ B(n+1) # nは列Aの順位で求めたい結果は、 # # A B C D # 1 40 35 1 # 2 80 50 0.4375 # 3 10 5 2.1875 # 4 20 15 0.546875 # 5 70 60 0.1171875 # # みたいな感じになります。 # # これってSQLで可能でしょうか? # DBMSはOracle11gR2です。 # # # '列Aで昇順にソートして一番小さい値を持つ行を基準に、以下の計算式で列Dを求めたいです。 D(n+1)= C(n)× D(n)÷ B(n+1)'(L) :- findsetof([_A,_B,_C],'TAB'(_A,_B,_C),LL), LL = [[_A,_B,_C]|R], '以下の計算式で列Dを求める。 D(n+1)= C(n)× D(n)÷ B(n+1)'(R,[_A,_B,_C,1],L). '以下の計算式で列Dを求める。 D(n+1)= C(n)× D(n)÷ B(n+1)'(R,L,L). '以下の計算式で列Dを求める。 D(n+1)= C(n)× D(n)÷ B(n+1)'([[_A_1,_B_1,_C_1]|R],[_A,_B,_C,_D],L) :- _D_1 is _C * _D / _B_1, '以下の計算式で列Dを求める。 D(n+1)= C(n)× D(n)÷ B(n+1)'(R,[_A_1,_B_1,_C_1,_D_1],L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/788 # # prd1テーブル # # p_id 商品ID # p_name 商品名前 # ---- # prd2テーブル # # p_id 商品ID # p_date 製造年 # ----- # prd3テーブル # # p_id # p_date # p_frame 種類1 # ---- # prd4テーブル # # p_frame # p_pattern 種類2(0又は1が入る) # ---- # prd1の商品IDとprd2の商品IDは1対Nの関係です。 # prd1の全商品に対して # prd1に対するprd2を抽出(inner join でも where でも)した以下のテーブル # # p_id p_date # 1 2001-01-01 # 1 2001-01-02 # 2 2001-01-01 # 2 2001-01-02 # 2 2001-01-03 # # に対して、prd3とprd4によって抽出したテーブルを結合するときに # 商品IDと製造年をキーに結合したいと思っています。 # # prd3はちなみに # # p_id p_date p_frame # 1 2001-01-01 1 # 1 2001-01-02 2 # 1 2001-01-03 3 # 1 2001-01-04 4 # 3 2001-01-01 5 # # prd4は、 # # p_frame p_pattern # 1 0 # 2 1 # 3 0 # 4 1 # 5 1 # 6 1 # # p_id p_date SUM(p_pattern_0) SUM(p_pattern_1) というテーブルを抽出したいです。 # # 1 2001-01-01 5 2 # 1 2001-01-02 3 NULL # 2 2001-01-01 NULL NULL # # といった感じです。prd1とprd2を結合したモノに、 prd3とprd4を結合したいのです。 # 'prd3とprd4によって抽出したテーブルを結合するときに商品IDと製造年をキーに結合する'(_p_id,_p_date,_sum_p_pattern_0,_sum_p_pattern_1) :- findsetof([_p_id,_p_date],( prd1(_p_id), prd2(_p_id,_p_date)), L1), append(_,[[_p_id,_p_date]|_],L1), prd3(_p_id,_p_date,_p_frame), findsum([_p_pattern_0,_p_pattern_1],( prd4(_p_frame,_p_pattern), p_pattern_x(_p_pattern,_p_pattern_0,_p_pattern_1)), [_sum_p_pattern_0,_sum_p_pattern_1]). p_pattern_x(0,1,0). p_pattern_x(1,0,1). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/730 # # MySQLで、以下のような2つのテーブルがあり、parent_idはparentの外部キーとなってます。 # # parent # id p_value # 1 AAA # 2 BBB # # children # parent_id c_value # 1 aaa # 1 bbb # 1 ccc # 2 ddd # 2 eee # # これを # # parent_id p_value c_value # 1 AAA (aaa, bbb, ccc) # 2 BBB (ddd, eee) # # のような形で取り出すことはできますか? # GROUP BYでparent_idでまとめることはできたのですが、c_valueをまとめて取り出す方法がわかりません。 # # 結合情報を一行に纏める(_parent_id,_p_value,_子供の名前ならび) :- findsetof(_parent_id,( parent(_parent_id,_)), _親の名前ならび), append(_,[_parent_id|R],_親の名前ならび), parent(_parent_id,_p_value), findall(c_value,( children(_parent_id,_c_value)), _子供の名前ならび). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/602 # # SQL Server2008 以下のテーブル「値段」から # # id | 食品 | 値段合計 | 値段1 | 値段2 | 値段3 # ________________________ # # 1 | 肉 |  500  |  500 | # 1 | 魚 |  300  |     | 300 # 1 | 卵 |  200 | 100 | 50 | 50 # 2 | 肉 |  350 | 250 | 100 # 2 | 魚 |  400 | 150 | 250 # # # 以下の結果を得て、新しくテーブル「値段合計」を作りたいです。 # # # id |値段id合計|肉値段合計|肉値段1|肉値段2|肉値段3|魚値段合計|魚値段1|魚値段2|魚値段3|卵値段合計|卵値段1|卵値段2|卵値段3| # _________________________________________________________________________________________________________________________________ # 1 | 1000 | 500 | 500 | | | 300 | | 300 | | 200 | 100 | 50 | 50 | # 2 | 750 | 350 | 250 | 100 | | 400 | 150 | 250 # # # 肉、魚、卵はそれぞれのidに一行しかなく、 # 肉と魚は必ずありますが、卵はあるとは限りません。 # シンプル縦横問題はわかったのですが、複雑になると一挙にわからなくなりました。。 # ご教示お願い致します。 # '「値段合計」を作る' :- findsetof(id,値段(_id,_,_,_,_,_),_idならび), append(_,[_id|R],_idならび), 食品の値段を得る(_id,肉,_肉値段合計,_肉値段1,_肉値段2,_肉値段3), 食品の値段を得る(_id,魚,_魚値段合計,_魚値段1,_魚値段2,_魚値段3), 食品の値段を得る(_id,卵,_卵値段合計,_卵値段1,_卵値段2,_卵値段3), _値段id合計 is _肉値段合計 + _魚値段合計 + _卵値段合計, assertz(値段合計(_id,_値段id合計,_肉値段合計,_肉値段1,_肉値段2,_肉値段3,_魚値段合計,_魚値段1,_魚値段2,_魚値段3,_卵値段合計,_卵値段1,_卵値段2,_卵値段3)), R = []. 食品の値段を得る(_id,_食品,_値段合計,_値段1,_値段2,_値段3) :- 値段(_id,_食品,_値段合計,_値段1,_値段2,_値段3),!. 食品の値段を得る(_id,_食品,0,0,0,0). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/597 # # 下記のようなデータがあるとき、投票回数が3以上に該当する投票者の # レコードを全て除いた結果が欲しいのですがどのようにしたらよいでしょうか? # 595ですがすみません重要なカラムを省いていました。 # その投票者を省くのはそのアンケートNoだけに限定したいのです # # アンケートNo ,投票者 ,投票回数, 誰に投票したか # ------------------------------- # 1   , A   , 1   , D # 1   , B   , 1   , E # 1   , B   , 2   , F # 1   , B   , 3   , G # 1   , C   , 2   , H # 1   , C   , 2   , I # 2   , A   , 1   , D # 2   , B   , 1   , E # 2   , C   , 1   , H # 2   , C   , 2   , I # 2   , C   , 3   , J # # 欲しいデータ # 1   , A   , 1   , D # 1   , C   , 2   , H # 1   , C   , 2   , I # 2   , A   , 1   , D # 2   , B   , 1   , E # # '投票回数が3以上に該当する投票者のレコードを全て除いた結果'(_アンケートNo,_投票者,_投票回数,_誰に投票したか) :- findsetof([_アンケートNo,_投票者],( データ(_アンケートNo,_投票者,_投票回数,_誰に投票したか), _投票回数 >= 3), L), データ(_アンケートNo,_投票者,_投票回数,_誰に投票したか), \+(member([_アンケートNo,_投票者],L)). findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/595 # # 下記のようなデータがあるとき、投票回数が3以上に該当する投票者の # レコードを全て除いた結果が欲しいのですがどのようにしたらよいでしょうか? # # 投票者 ,投票回数, 誰に投票したか # ------------------------------- # A   , 1   , D # B   , 1   , E # B   , 2   , F # B   , 3   , G # C   , 2   , H # C   , 2   , I # # (3以上に該当する投票者Bのレコードを除く) # A   , 1   , D # C   , 2   , H # C   , 2   , I # # '投票回数が3以上に該当する投票者のレコードを全て除いた結果'(_投票者,_投票回数,_誰に投票したか) :- findsetof(_投票者,( データ(_投票者,_投票回数,_誰に投票したか), _投票回数 >= 3), L), データ(_投票者,_投票回数,_誰に投票したか), \+(member(_投票者,L)). findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/558 # # create table aaa ( # id integer not null, # test text not null, # test2 integer not null, # unique (id,test) # ); # # create table bbb ( # id integer not null, # test text not null, # test2 integer not null # unique (id,test) # ); # # aaa # id test test2 # 10 aaa 100 # 10 bbb 200 # 10 ccc 100 # 10 ddd 100 # # bbb # id test test2 # 10 aaa 200 # 10 bbb 100 # # ほしい結果 # id test test2 # 10 aaa 200 # 10 bbb 100 # 10 ccc 100 # 10 ddd 100 # aaa(10,111,200). aaa(10,bbb,100). bbb(10,aaa,200). bbb(10,bbb,100). bbb(10,ccc,100). bbb(10,ddd,100). ほしい結果(_id,_test,_test2) :- findall([_id,_test,_test2],( aaa(_id,_test,_test2)), LL1), findall([_id,_test,_test2],( bbb(_id,_test,_test2)), LL2), append(LL1,LL2,LL), findsetof([_id,_test],( append(_,[[_id,_test]|_],LL)), LL3), findmax([_test2,_id,_test],( append(_,[[_id,_test]|_],LL3), append(_,[[_id,_test,_test2]|_],LL)), LL4), append(_,[[_test2,_id,_test]|_],LL4). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/429 # # ・DB2 v9.5 # ・テーブルの内容 # ■テーブル成績 # 名前,教科コード,点数 # ========== # Aさん,1,50 # Aさん,2,70 # Bさん,3,80 # # ■テーブル教科 # 教科コード,教科名 # ========== # 1,数学 # 2,国語 # 3,社会 # # ・欲しい結果 # Aさん,数学,50 # Aさん,国語,70 # Aさん,社会,0 # Bさん,数学,0 # Bさん,国語,0 # Bさん,社会,80 # # ・説明 # どう結合したら目的の結果が得られるかわかりません。 # おしえてくださいますでしょうか。 # 成績('Aさん','1',50). 成績('Aさん','2',70). 成績('Bさん','3',80). 教科('1',数学). 教科('2',国語). 教科('3',社会). 成績の表示 :- '成績と教科の結合。ただし、成績がない教科の点数は0とする'(_教科成績ならび), append(_,[[[_名前,_教科名,_点数]|R],_教科成績ならび), writef('%t,%t,%t\n',[_名前,_教科名,_点数]), R = []. '成績と教科の結合。ただし、成績がない教科の点数は0とする'(_教科成績ならび) :- findsetof(_名前,成績(_名前,_,_),_名前ならび), findall([_名前,_教科名,_点数],( append(_,[_名前|R],_名前ならび), 教科(_教科コード,_教科名), 科目成績を得る(_名前,_教科コード,_点数)), _教科成績ならび). 科目成績を得る(_名前,_教科コード,_点数) :- テーブル成績(_名前,_教科コード,_点数),!. 科目成績を得る(_,_,0). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1301067486/220 # # ●正規表現の使用環境 # grepとかegrepとか # # ●検索か置換か? # 検索 # # ●説明 # a,nの2文字のみが含まれる行を検索したい # # ●対象データ # aaa # ann # nana # anana # sin # anans # # ●希望する結果 # 上4つのみ出力 # 下二つは引っかからない # # 'a,nの2文字のみが含まれる行を検索したい'(_行ならび,_行) :- append(_,[_行|_],_行ならび), findsetof(_文字,sub_atom(_行,_,1,_,_文字),[a,n]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/402 # # 下記のようなユーザーに対する取得ポイントと、消費したポイントのテーブルがあり、 # それらの合計を各ユーザー毎にまとめたいのですが、どうしたらいいでしょうか? # # [取得テーブル t1] # id | user_id | point # --+-------+----- # 1 | 1    | 30 # 2 | 2    | 10 # 3 | 3    | 50 # 4 | 1    | 20 # 5 | 2    | 10 # 6 | 3    | 50 # # [消費テーブル t2] # id | user_id | used_point # --+-------+----- # 1 | 1    | -10 # 2 | 2    | -10 # 3 | 4    | -50 # 4 | 1    | -20 # 5 | 4    | -10 # # <欲しい結果> # user_id | point # -------+----- # 1    | 20 # 2    | 10 # 3    | 100 # 4    | -60 # # # DBMSはMySQLです。 # お願いしますm(_ _)m # # t1(1,1,30). t1(2,2,10). t1(3,3,50). t1(4,1,20). t1(5,2,10). t1(6,3,50). t2(1,1,-10). t2(2,2,-10). t2(3,4,-50). t2(4,1,-20). t2(5,4,-10). '下記のようなユーザーに対する取得ポイントと、消費したポイントのテーブルがあり、それらの合計を各ユーザー毎にまとめたい'(_ユーザごとの合計) :- ユーザを取得(L), findall([_user_id,_合計],( append(_,[_user_id|_],L), t1テーブルの合計(_user_id,_合計1), t2テーブルの合計(_user_id,_合計2), _合計 is _合計1 - _合計2), _ユーザごとの合計). ユーザを取得(L) :- findsetof(_user_,t1(_user_id,_),L1), findsetof(_user_,t2(_user_id,_),L2), 和集合(L1,L2,L). t1テーブルの合計(_user_id,_合計) :- findsum(_point,t1(_user_id,_point),_合計). t2テーブルの合計(_user_id,_合計) :- findsum(_userpoint,t2(_user_id,_userpoint),_合計). 和集合(_集合1,_集合2,_和集合) :- append(_集合1,_集合2,_ならび3), findall(_要素,( append(L0,[_要素|_],_ならび3), \+(append(_,[_要素|_],L0))), _和集合) . % 参照 % findsum/3 http://nojiriko.asia/prolog/findsum.html % findsetof/3 http://nojiriko.asia/prolog/findsetof.html % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/324 # # NAME FRUIT NUM # # TARO banana 10 # TARO orange 4 # TARO tomato 3 # TARO grape 2 # TARO apple 1 # TARO melon 1 # TARO mango 1 # HANAKO tomato 30 # HANAKO orange 21 # HANAKO apple 2 # HANAKO banana 1 # GEN mango 12 # GEN grape 6 # GEN orange 4 # GEN banana 1 # GEN apple 1 # # # というテーブルで、各人間の持つ果物のうち上位3種類を取得したいのですが、 # どうすればよろしいでしょうか? # # 欲しい結果 # NAME FRUIT NUM # # TARO banana 10 # TARO orange 4 # TARO tomato 3 # HANAKO tomato 30 # HANAKO orange 21 # HANAKO apple 2 # GEN mango 12 # GEN grape 6 # GEN orange 4 # # # SQLserver2008です。よろしくお願いいたします。 # # テーブルで、各人間の持つ果物のうち上位3種類を取得したい :- findsetof(_名前,テーブル(_名前,_果物,_数量),LL1), append(_,[_名前|R],LL1), findall([_名前,_数量,_果物],( テーブル(_名前,_果物,_数量)), LL2), 大きい順に(LL2,LL3), 上位3位(LL3,[_名前,_果物,_数量]), writef('%t %t %t\n',[_名前,_果物,_数量]), R = []. 大きい順に(L1,L2) :- sort(L1,L3), reverse(L3,L2),!. 上位3位(L,[_名前,_果物,_数量]) :- append(L0,[[_名前,_数量,_果物]|_],L), length(L0,Length), Length =< 2. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/300 # # 上手くいかないので質問させてください。 # ACCESS2007を使っています。 # 年フィールドと月フィールドを用いて「年度」の件数を抽出したいのですが、 # 以下のクエリでは月部分が干渉してか上手く抽出出来ません。 # # 22年4月〜23年3月 といった結果を出したいのですがどうしたらよいでしょうか? # # SELECT 年 FROM Table1 # WHERE (年>21 AND 月>3) AND (年<23 AND 月<4) # # '年フィールドと月フィールドを用いて「年度」の件数を抽出したい'(_テーブル,L) :- テーブル構造(_テーブル,年,M), テーブル構造(_テーブル,月,N), findmax(U,テーブル構造(_テーブル,_,U),Max), length(L1,Max), nth1(M,L1,_年), nth1(N,L1,_月), P =.. [_テーブル|L1], findall(_年度,( P, 年度のルール(_年,_月,_年度)), _年度ならび), findsetof(_年度,( append(_,[_年度|_],_年度ならび), L2), findall([_年度,_度数],( append(_,[_年度|_],L2), count(append(_,[_年度|_],_年度ならび),_度数)), L). 年度のルール(_年,_月,_年度) :- _月 >= 4, _年 = _年度,!. 年度のルール(_年,_月,_年度) :- _月 < 4, _年度 is _年 - 1,!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/288 # # sqlite v3.6.23.1で、 # comment (text) ,postedtime (int) という形式にて掲示板を作っているのですが、 # 「最新の5コメント、但し、24時間以内の投稿については最大50個まで」を求めたくて # # SELECT comment FROM mm ORDER BY postedtime DESC LIMIT 50 # UNION # SELECT comment FROM mm WHERE postedtime > $nowtime - 3600*24 ORDER BY ptime DESC LIMIT 50 # # としてみたのですが($nowtimeには今の時間を入れてます)、 # 1st ORDER BY term does not match in the result set というエラーが出ます。 # (union前後のクエリそれぞれ単独ではエラーは出ません) # # 欲しい結果を求めるにはどのように書けばいいのでしょうか? # # '最新の5コメント、但し、24時間以内の投稿については最大50個まで'(_テーブル,_現在の時刻,P) :- split(_現在の時刻,[' ','/','-',':','.'],[_年,_月,_日,_時,_分,_秒,_]), テーブル構造(_テーブル,時刻,N), findmax(M,テーブル構造(_テーブル,_,M),Max), length(L1,Max), nth1(N,L1,_時刻), P =.. [_テーブル|L1], 選択(P,_年,_月,_日,_時,_分,_秒,L), append(_,[_時刻|_],L), call(P). 選択(P,_年,_月,_日,_時,_分,_秒,L) :- findsetof(_時刻,( call(P), 時刻が24時間以内(_年,_月,_日,_時,_分,_秒,_時刻)), L1), 要素切り取り(L1,L),!. 選択(P,_年,_月,_日,_時,_分,_秒,L) :- findall(_時刻,( call(P), 時刻が24時間以内(_年,_月,_日,_時,_分,_秒,_時刻)), L1), 整列(L1,L2), 要素切り取り(L2,L),!. 選択(P,_,_,_,_,_,_,L) :- findall(_時刻,( call(P)), L1), 整列(L1,L2), length(L,5), append(_,L,L2),!. 要素切り取り(L1,L) :- length(L1,Length), Length >= 50, length(L,50), append(_,L,L1),!. 要素切り取り(L1,L1) :- length(L1,Length), Length >= 5, length < 50,!. 時刻が24時間以内(_年,12,31,_時,_分,_秒,_時刻) :- split(_時刻,['/','-',':','.'],[_年_2,_月_2,_日_2,_時_2,_分_2,_秒_2,_]), _年_1 is _年 + 1, [_年_1,1,1,_時,_分,_秒,_時刻] @>= [_年_2,_月_2,_日_2,_時_2,_分_2,_秒_2,_]),!. 時刻が24時間以内(_年,2,29,_時,_分,_秒,_時刻) :- うるう年(_年), [_年,3,1,_時,_分,_秒,_時刻] @>= [_年_2,_月_2,_日_2,_時_2,_分_2,_秒_2,_]),!. 時刻が24時間以内(_年,2,28,_時,_分,_秒,_時刻) :- \+(うるう年(_年)), [_年,3,1,_時,_分,_秒,_時刻] @>= [_年_2,_月_2,_日_2,_時_2,_分_2,_秒_2,_]),!. 時刻が24時間以内(_年,_月,30,_時,_分,_秒,_時刻) :- append(_,[_月|_],[4,6,9,11]), _月_1 is _月 + 1, [_年,_月_1,1,_時,_分,_秒,_時刻] @>= [_年_2,_月_2,_日_2,_時_2,_分_2,_秒_2,_]),!. 時刻が24時間以内(_年,_月,31,_時,_分,_秒,_時刻) :- append(_,[_月|_],[1,3,5,7,8,10]), _月_1 is _月 + 1, [_年,_月_1,1,_時,_分,_秒,_時刻] @>= [_年_2,_月_2,_日_2,_時_2,_分_2,_秒_2,_]),!. 時刻が24時間以内(_年,_月,_日,_時,_分,_秒,_時刻) :- split(_時刻,['/','-',':','.'],[_年_2,_月_2,_日_2,_時_2,_分_2,_秒_2,_]), _日_1 is _日 + 1, [_年,_月,_日_1,_時,_分,_秒,_時刻] @>= [_年_2,_月_2,_日_2,_時_2,_分_2,_秒_2,_]),!. うるう年(_年文字列) :- atom(_年文字列), atom_to_term(_年文字列,_年整数,_), !, うるう年(_年整数) . うるう年(_年) :- 0 is _年 mod 400,!. うるう年(_年) :- 0 is _年 mod 100, !, fail. うるう年(_年) :- 0 is _年 mod 4,!. うるう年(_年) :- \+(0 is _年 mod 4), fail. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1294641578/215 # # one_side the_other value # 30 31 23 # 31 30 23 # 4 31 20 # 31 6 20 # 6 31 20 # 31 4 20 # 19 30 19 # 30 19 19 # 7 27 17 # 35 18 17 # : : : # # one_sideとthe_otherのペアとして認識して # 逆順になっているだけのペアは纏める方法を教えて下さい # 'one_sideとthe_otherのペアとして認識して逆順になっているだけのペアは纏める方法を教えて下さい'(_テーブル名,_逆順になっているペア) :- findall([_one_side,_the_other],( 'one_sideとthe_otherのペアとして認識して逆順になっているだけのペアは纏める方法を教えて下さい'(_テーブル名,_one_side,_the_other,L2)), _逆順になっているペア). 'one_sideとthe_otherのペアとして認識して逆順になっているだけのペアは纏める方法を教えて下さい'(_テーブル名,_one_side,_the_other,L2) :- P =.. [_テーブル名,_one_side,_the_other,_value], findsetof([_one_side,_the_other],( call(P)), L1), append(_,[[_one_side,_the_other]|_],L1), findall(_value,( call(P)), L2), ニ要素以上の逆順ならび(L2). ニ要素以上の逆順ならび([A,B]) :- A @> B,!. ニ要素以上の逆順ならび([A,B|R1]) :- A @> B, ニ要素以上の逆順ならび([B|R]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1301553333/680 # # 1]授業単元:プログラミング # [2]問題文:自己参照型構造体を用いて、以下の処理をするプログラムを作成せよ。 # # 正の数入力→連結リストを辿り、初めて入力された数ならばカウンタを1増やす。同じ数が続けて入力されたらその数のカウンタをさらに1増やす。 # 負の数入力→負の数の絶対値と同じ回数入力された数のデータを削除(例えば、-3を入力し、それ以前に14が3回入力されていたら、それを削除) # 0を入力→データを出力して終了。 # # データ出力→終了の流れはどうにかなりましたが、それ以外で上手い発想が思いつきません。 # # http://ime.nu/codepad.org/yayuXIUa # # 期限は明日までです。 # # 正の数入力後連結リストを辿り、初めて入力された数ならばカウンタを1増やす。負の数入力後負の数の絶対値と同じ回数入力された数のデータを削除0を入力後データを出力して終了 :- 数入力(_数), 連結リストとカウンタを更新していく(_数,[],0,_連結リスト,_カウンタ), データを出力して終了(_連結リスト,_カウンタ),!. 連結リストとカウンタを更新していく(_数,L_1,_カウンタ_1,L,_カウンタ) :- 負の数が入力されたら負の数の絶対値と同じ回数入力された数のデータを削除して連結リストの最後に0を加える(_数,L_1,_カウンタ_1,L,_カウンタ),!. 連結リストとカウンタを更新していく(_数,L_1,_カウンタ_1,L,_カウンタ) :- 初めて入力された数ならばカウンタを1増やす(_数,L_1,_カウンタ_1,L_2,_カウンタ_2), 数入力(_数_2), 連結リストとカウンタを更新していく(_数_2,L_2,_カウンタ_3,L,_カウンタ). 連結リストとカウンタを更新していく(_数,L_1,_カウンタ_1,L,_カウンタ) :- \+(初めて入力された数ならばカウンタを1増やす(_数,L_1,_カウンタ_1,L,_カウンタ)), 数入力(_数_2), 連結リストの最後に数を追加(_数,L_1,L_2), 連結リストとカウンタを更新していく(_数_2,L_2,_カウンタ_1,L,_カウンタ). データを出力して終了(_連結リスト,_カウンタ) :- writef('実行後の連結リストは %t です\nその時点のカウンタは %t です\n',[_連結リスト,_カウンタ]),!. 負の数が入力されたら負の数の絶対値と同じ回数入力された数のデータを削除して連結リストの最後に0を加える(_負の数,L_1,_カウンタ_1,L_2,_カウンタ_2) :- _負の数 < 0, _負の数の絶対値 is abs(_負の数), 負の数の絶対値と同じ回数入力された数のデータを削除(_負の数の絶対値,L_1,L_3), 連結リストの最後に0を加える(L3,L2),!. 連結リストの最後に0を加える(L3,L2) :- append(L_3,[0],L_2),!. 負の数の絶対値と同じ回数入力された数のデータを削除(_負の数の絶対値,L_1,L_2) :- 既に入力された重複しない数ならびを得る(L_1,_数ならび), 削除する数を選択する(_負の数の絶対値,_数ならび,L_1,_削除する数候補), 連結リストからデータを削除(_削除する数候補,L_1,L_2). 既に入力された重複しない数ならびを得る(L_1,_数ならび) :- findsetof(_数,append(_,[_数|_],L_1),_数ならび),!. 削除する数を選択する(_負の数の絶対値,_数ならび,L_1,_削除する数候補) :- findall(_数,( append(_,[_数|_],_数ならび), 負の数の絶対値に要素数が一致する数(_負の数の絶対値,L_1,_数)), _削除する数候補),!. 負の数の絶対値に要素数が一致する数(_負の数の絶対値,L_1,_数) :- count(append(_,[_数|_],L_1),_負の数の絶対値)),!. 連結リストからデータを削除([],L,L) :- !. 連結リストからデータを削除([_数|R],L_1,L) :- ならびから削除(_数,L_1,L_2), 連結リストからデータを削除(R,L_2,L). ならびから削除(_,[],[]) :- !. ならびから削除(_削除する要素,[_削除する要素|_残り対象ならび],_削除されたならび) :- ならびから削除(_削除する要素,_残り対象ならび,_削除されたならび),!. ならびから削除(_削除する要素,[_要素|_残り対象ならび],[_要素|_残り削除ならび]) :- ならびから削除(_削除する要素,_残り対象ならび,_残り削除ならび),!. 初めて入力された数ならばカウンタを1増やす(_数,L_1,_カウンタ_1,L_2,_カウンタ_3) :- \+(append(_,[_数|_],L_1)), _カウンタ_2 is _カウンタ_1 + 1, 同じ数が続けて入力されたらその数のカウンタをさらに1増やす(_数,L_1,_カウンタ_2,_カウンタ_3), 連結リストの最後に数を追加(_数,L_1,L_2),!. 同じ数が続けて入力されたらその数のカウンタをさらに1増やす(_数,L_1,_カウンタ_1,_カウンタ_2) :- last(L_1,_数), _カウンタ_2 is _カウンタ_1 + 1,!. 同じ数が続けて入力されたらその数のカウンタをさらに1増やす(_,_,_カウンタ_1,_カウンタ_1). 連結リストの最後に数を追加(_数,L_1,L_2) :- append(L_1,[_数],L_2). 数入力(_数) :- write('数を入力してください : '), get_line(Line), 数入力診断(Line,_数),!. 数入力(_数) :- 数入力(_数). 数入力診断(Line,_数) :- atom_to_term(Line,_数,_), number(_数),!. 数入力診断(Line,_数) :- writef('入力された %t からは数値が得られません。再入力をお願いします\n',[Line]), fail. % 以下のサイトは # もう一度。テーブルtableにキーAの列とキーBの列がある。 # キーBは時系列で、例えば2011年5月6日なら20110506みたいな感じ。 # 昨日なら20110505だな。つまりプライマリではある。 # こいつをキーA毎に上位5つずつ抜き出したデータテーブル(VIEW)を作りたい # 曜日ごとに、日付の早い順5tuplesをとりだす。 # # 曜日(金曜,'20110401'). # 曜日(月曜,'20110404'). # 曜日(火曜,'20110405'). # 曜日(水曜,'20110406'). # 曜日(金曜,'20110408'). # 曜日(土曜,'20110409'). # 曜日(月曜,'20110411'). # 曜日(火曜,'20110412'). # 曜日(木曜,'20110414'). # 曜日(金曜,'20110415'). # 曜日(土曜,'20110416'). # 曜日(日曜,'20110417'). # 曜日(月曜,'20110418'). # 曜日(火曜,'20110419'). # 曜日(木曜,'20110421'). # 曜日(金曜,'20110422'). # 曜日(土曜,'20110423'). # 曜日(月曜,'20110425'). # 曜日(火曜,'20110426'). # 曜日(水曜,'20110427'). # 曜日(木曜,'20110428'). # 曜日(日曜,'20110501'). # 曜日(月曜,'20110502'). # 曜日(火曜,'20110503'). # 曜日(水曜,'20110504'). # 曜日(木曜,'20110505'). # 曜日(土曜,'20110507'). # 曜日(日曜,'20110508'). # 曜日(月曜,'20110509'). # 曜日(火曜,'20110510'). # 曜日(金曜,'20110513'). # 曜日(土曜,'20110514'). # 曜日(日曜,'20110515'). # 曜日(火曜,'20110517'). # 曜日(水曜,'20110518'). # 曜日(木曜,'20110519'). # 曜日(日曜,'20110522'). # 曜日(月曜,'20110523'). # 曜日(火曜,'20110524'). # 曜日(水曜,'20110525'). # 曜日(木曜,'20110526'). # 曜日(金曜,'20110527'). # 曜日(土曜,'20110528'). # 曜日(日曜,'20110529'). # 曜日(月曜,'20110530'). # 曜日(火曜,'20110531'). 曜日ごとの最初の五つの日付(_曜日,_最初の五つの日付ならび) :- eachsetof(_曜日,曜日(_曜日,_日付),_曜日_1), setof(_日付_1,曜日(_曜日_1,_日付_1),L), limit_n(5,L,_最初の五つの日付ならび). %%%% 汎用述語(ユーザ定義) %%%% limit_n(N,L,_limit_n_L) :- length(L,Len), Len < N, L = _limit_n_L),!. limit_n(N,L,_limit_n_L) :- length(_limit_n_L,N), append(_limit_n_L,_,L). eachsetof(A,B,E) :- findsetof(A,B,L), append(_,[E|_],L). findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). % 以下のサイトは # I am sorry to ask this question, but it has been a lot since I programmed in Prolog. I think I am used to imperative paradigm. :-( # # I am trying to obtain itemsets from a Prolog relation # # % transaction(Time, Client, Item) # transaction(1, 2, 10). # transaction(1, 2, 20). # transaction(2, 5, 90). # transaction(3, 2, 30). # transaction(4, 2, 40). # transaction(4, 2, 60). # transaction(4, 2, 70). # transaction(5, 4, 30). # transaction(5, 3, 30). # transaction(5, 3, 50). # transaction(5, 3, 70). # transaction(5, 1, 30). # transaction(6, 1, 90). # transaction(6, 4, 40). # transaction(6, 4, 70). # transaction(7, 4, 90). # # % Transformation of transactions to Lists of items per Time per Client. # transaction2(Time, Client, List) :- # setof(Item, Time^Client^transaction(Time, Client, Item), List). # # % Itemsets. # itemsets :- # transaction(Time, Client, _), # transaction2(Time, Client, List), # assert(init(List)). # % Main: # main(Itemsets) :- # itemsets, # setof(Basket, init(Basket), Itemsets), # retractall(init(Basket)). # Then if I consult main(X) I would like to obtain: # # X = [[10, 20], [30], [30, 50, 70], [40, 60, 70], [40, 70], [90]] # I just can't figure out a proper way of doing this. # # If I can get a pointer or a little help I will appreciate very much. # main(Items) :- findsetof([T1,C1],transaction(T1,C1,_),L1), findsetof(L2,( append(_,[[T2,C2]|_],L1), findsetof(Item,transaction(T2,C2,Item),L2)), Items). findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/137 # # お世話になっています。 # # どのようなSQLになるか教えてください。 # # テーブルA テーブルB テーブルC # E111,001,AR E111,001,AR E111,001,AR # E111,001,AY E111,001,AY E111,001,AY # E111,002,AR E111,003,AR E111,004,AR # # 上記のような同じキー項目(ID,番号,コード)を持つ3つのテーブルがあるとき、 # # E111,001,AR,E111,001,AR,E111,001,AR # E111,001,AY,E111,001,AY,E111,001,AY # E111,002,AR,'','','','','','' # '','','',E111,003,AR,'','','' # '','','','','','',E111,004,AR # # の形でレコードを取得するにはどのようなSQLになりますか? # # お願いします。 # # # '上記のような同じキー項目(ID,番号,コード)を持つ3つのテーブルがあるとき、3レコードを併記する'(L) :- findsetof([A,B],テーブルA(A,B,_),L1), findsetof([A,B],テーブルB(A,B,_),L2), findsetof([A,B],テーブルC(A,B,_),L3), append(L1,L2,L3,L4), findsetof([A,B],append(_,[[A,B]|_],L4),L5), findall([A1,B1,X,A2,B2,Y,A3,B3,Z],( append(_,[[A,B]|_],L5), '3レコード選択'(A,B,A1,B1,X,A2,B2,Y,A3,B3,Z), \+((X='',Y='',Z=''))),L). '3レコード選択'(A,B,A1,B1,X,A2,B2,Y,A3,B3,Z) :- 選択A(A,B,A1,B1,X), 選択B(A,B,A2,B2,Y), 選択C(A,C,A3,B3,Z). 選択A(A,B,'','','') :- \+(テーブルA(A,B,X)),!. 選択A(A,B,A,B,X) :- テーブルA(A,B,X). 選択B(A,B,'','','') :- \+(テーブルB(A,B,X)),!. 選択B(A,B,A,B,X) :- テーブルB(A,B,X). 選択C(A,B,'','','') :- \+(テーブルC(A,B,X)),!. 選択C(A,B,A,B,X) :- テーブルC(A,B,X). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1301553333/212 # # [1]C言語演習 # [2]問題文 # 次の形式のタブ区切りファイルがある。(行数は最大で1000万行とする) # 生徒ID クラス名 国語得点 数学得点 英語得点 # 生徒IDは8桁の0から9で構成される文字列 # クラス名は4桁の0から9で構成される文字列 # 国語得点、数学得点、英語得点は3桁の0から9で構成される文字列とする。 # # (2)それぞれの教科の得点が所属しているクラスの各教科の平均点の大小関係と # 同じ生徒をリストアップせよ # ただしあるクラスの2つの教科の平均点が一致している場合はその2つの教科の得点の # 大小関係は不問として出力する。(3つが一致している場合はそのクラスの生徒全員 # がリストアップされることになる # [3] OSはLinux,言語はCです。(C++は不可) # [4] 4/30まで # [5] stdlib.h stdio.h string.hをincludeしても良いがそれ以外は不可だそうです # よろしくお願いします。 # # それぞれの教科の得点が所属しているクラスの各教科の平均点の大小関係が同じ生徒をリストアップ(_ファイル) :- get_split_lines(_ファイル,['\t'],LL), findsetof(_クラス,append(_,[[_,_クラス,_,_,_]|_],LL),_クラスならび), findall([_クラス,_パターン],( append(_,[_クラス|_],_クラスならび), パターン(LL,_クラス,_国語平均点,_数学平均点,_英語平均点,_パターン)), _クラス・パターンならび), append(_,[[_ID,_クラス,_国語,_数学,_英語]|R],LL), パターンが一致したら表示(_ID,_クラス,_クラスパターンならび,_国語,_数学,_英語), R = [],!. パターンが一致したら表示(_ID,_クラス,_クラス・パターンならび,_国語,_数学,_英語) :- append(_,[[_クラス,_パターン]|_],_クラス・パターンならび), パターン判断(_パターン,_国語,_数学,_英語), write_formatted('%t\n',[_クラス,_ID]),!. パターンが一致したら表示(_,_,_,_,_,_). パターン(LL,_クラス,_国語平均点,_数学平均点,_英語平均点,_パターン) :- findavg(_国語,append(_,[[_,_クラス,_国語,_,_]|_],LL),_国語平均点), findavg(_数学,append(_,[[_,_クラス,_数学,_,_]|_],LL),_数学平均点), findavg(_英語,append(_,[[_,_クラス,_英語,_,_]|_],LL),_英語平均点), パターン(_パターン,_国語平均点,_数学平均点,_英語平均点). パターン(1,A,B,C) :- A >B,B > C,!. パターン(2,A,B,C) :- A >C,C > B,!. パターン(3,A,B,C) :- B >A,A > C,!. パターン(4,A,B,C) :- B >C,C > A,!. パターン(5,A,B,C) :- C >A,A > B,!. パターン(6,A,B,C) :- C >B,B > A,!. パターン(7,E,E,C) :- \+(E=C),E > C,!. パターン(8,E,E,C) :- \+(E=C),E < C,!. パターン(9,E,B,E) :- \+(E=B),E > B,!. パターン(10,E,B,E) :- \+(E=B),E < B,!. パターン(11,A,E,E) :- \+(E=C),E < A,!. パターン(12,A,E,E) :- \+(E=C),E > A,!. パターン(13,E,E,E). パターン判断(_パターン,A,B,C) :- _パターン < 7, パターン(_パターン,A,B,C),!. パターン判断(7,A,B,C) :- C < A,C < B,!. パターン判断(8,A,B,C) :- C > A,C > B,!. パターン判断(9,A,B,C) :- B < A,B < C,!. パターン判断(10,A,B,C) :- B > A,B > C,!. パターン判断(11,A,E,E) :- A < B,A < C,!. パターン判断(12,A,E,E) :- A > B,A > C,!. パターン判断(13,_,_,_). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1301553333/212 # # [1]C言語演習 # [2]問題文 # 次の形式のタブ区切りファイルがある。(行数は最大で1000万行とする) # 生徒ID クラス名 国語得点 数学得点 英語得点 # 生徒IDは8桁の0から9で構成される文字列 # クラス名は4桁の0から9で構成される文字列 # 国語得点、数学得点、英語得点は3桁の0から9で構成される文字列とする。 # # (1)各教科の得点の和が同じ生徒達のグループについて、そのグループが何人で何クラスの # 生徒から構成されているかを、得点和毎に表出力せよ # ただし0人で構成されるグループについては出力する必要がない。 # 形式例 # 得点:123 人数:5人 グループ数:4 # 得点:128 人数:3人 グループ数:3 # 得点:214 人数:11人 グループ数:9 # ............ # # (2)それぞれの教科の得点が所属しているクラスの各教科の平均点の大小関係と # 同じ生徒をリストアップせよ # ただしあるクラスの2つの教科の平均点が一致している場合はその2つの教科の得点の # 大小関係は不問として出力する。(3つが一致している場合はそのクラスの生徒全員 # がリストアップされることになる # [3] OSはLinux,言語はCです。(C++は不可) # [4] 4/30まで # [5] stdlib.h stdio.h string.hをincludeしても良いがそれ以外は不可だそうです # よろしくお願いします。 # # '各教科の得点の和が同じ生徒達のグループについて、そのグループが何人で何クラスの生徒から構成されているかを、得点和毎に表出力せよ'(_ファイル) :- get_split_lines(_ファイル,['\t'],LL), findall([_得点合計,_クラス名],( append(_,[[_生徒ID,_クラス名,_国語得点,_数学得点,_英語得点]|_],LL), _得点合計 is _国語得点,_数学得点,_英語得点), L1), findsetof(_得点合計,( append(_,[[_得点合計,_]|_,L1)), L2), findsetof([_得点合計,_クラス]( append(_,[[_得点合計,_クラス]|_,L1)), L3), findall([_得点合計,_グループ人数,_クラス数],( append(_,[_得点合計|_],L2), count(append(_,[[_得点合計,_]|_],L1),_グループ人数)), count(append(_,[[_得点合計,_]|_],L3),_クラス数)), _得点合計・グループ人数・クラス数集計ならび), 出力する(_得点合計・グループ人数・クラス数集計ならび). 出力する(_得点合計・グループ人数・クラス数集計ならび) :- append(_,[[_得点合計,_グループ人数,_クラス数]|R],_得点合計・グループ人数・クラス数集計ならび), write_formatted('得点:%t 人数:%t人 グループ数:%t\n',[_得点合計,_グループ人数,_クラス数]), R = [],!. % 以下のサイトは # http://bit.ly/dIOWsn test(t1,[a,b,c]). test(t2,[a,b]). test(t3,[a,d]). test(t4,[e,f]). test(t5,[e,f,b,c,a]). ある要素を含む集合名を蒐集する(_要素ならび,_蒐集された集合名) :- findsetof(_集合名,( append(_,[_要素|_],_要素ならび), test(_集合名,_集合), append(_,[_要素|_],_集合)), _蒐集された集合名). findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/106 # # ストアドプロシージャについて質問させてください。 # # 簡単な結果を返すクエリ # SELECT A,B,C FROM TEST # # といったクエリの結果を戻り値として返すストアドを作成したいのですが # どのように書けば良いのかわかりません。 # # 単一の列のみを返す方法ならわかったのですが、複数列を返す方法が # 分からないといった状態です。 # テーブル構造('TEST',1,'A'). テーブル構造('TEST',2,'B'). テーブル構造('TEST',3,'C'). 簡単な結果を返すクエリ(_テーブル名,_選択項ならび,_値ならび) :- count(テーブル構造('TEST',_,_),Len), length(_値ならび,Len), findsetof(_,( テーブル構造(_テーブル名,Nth,_)), L), P =.. [_テーブル|_変数ならび], call(P), 選択項と値の結合(L,_選択項ならび,_値ならび). 選択項と値の結合(_テーブル名,L,[],[]) :- !. 選択項と値の結合(_テーブル名,L,[_選択項|R1],[_値|R2]) :- テーブル構造(_テーブル名,Nth,_選択項), list_nth(Nth,L,_値), 選択項と値の結合(_テーブル名,L,R1,R2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/92 # # 環境はoracle9iです。 # # ■テーブルの構成 # |年度|月|部署コード|商品コード|金額| # # ■テーブルの内容 # |2010|01|AAA|001|1000| # |2010|02|AAA|001|2000| # |2010|01|AAA|001|3000| # |2010|01|AAA|002|3000| # |2010|02|BBB|003|4000| # |2010|01|CCC|001|5000| # |2010|03|CCC|001|6000| # # 上記のようなテーブルがあり、 # これを # と、ここまでなら上の4つでGROUP BYしてあげれば良いのですが、 # そこに年度,部署コード,商品コードでサマリした # 「累計金額」列を加える必要があります。(イメージは下記のとおりです。) # # # ■抽出結果の構成 # |年度|月|部署コード|商品コード|金額|累計金額| # # ■抽出結果の内容 # |2010|01|AAA|001|4000|6000| # |2010|02|AAA|001|2000|6000| # |2010|02|BBB|003|4000|4000| # |2010|01|CCC|001|5000|11000| # |2010|03|CCC|001|6000|11000| # # # GROUP BYと別の集計単位で列を作ることが可能か、 # 可能であればどのようなSQLを書くべきか、 # というところを教えてください。 # # '|年度|月|部署コード|商品コード|金額| テーブルを年度,月,部署コード,商品コードでサマリした値にさらに年度,部署コード,商品コードでサマリした値を付加した行表示' :- 鍵ならびの生成([_年度,_部署コード,_商品コード],テーブル(_年度,_月,_部署コード,_商品コード,_金額),_鍵ならびの一), 鍵ならびの生成([_年度,_月,_部署コード,_商品コード],テーブル(_年度,_月,_部署コード,_商品コード,_金額),_鍵ならびの二), append(_,[[_年度,_部署コード,_商品コード]|R],_鍵ならびの一), 金額制約(_鍵ならびの二,_年度,_月,_部署コード,_商品コード,_金額月合計,_金額総合計), writef('|%t|%t|%t|%t|%t|%t\n',[_年度,_月,_部署コード,_商品コード,_金額月合計,_金額総合計]), R = []. 金額集約(L2,_年度,_月,_部署コード,_商品コード,_金額月合計,_金額総合計) :- 年度・部署コード・商品コード集約(_年度,_部署コード,_商品コード,_金額総合計), append(_,[[_年度,_月,_部署コード,_商品コード]|_],L2), 年度・月・部署コード・商品コード集約(_年度,_月,_部署コード,_商品コード,_金額月合計). 年度・月・部署コード・商品コード集約(_年度,_月,_部署コード,_商品コード,_金額合計) :- findsum(_金額,( テーブル(_年度,_月,_部署コード,_商品コード,_金額)), _年度・月・部署コード・商品コード集約). 年度・部署コード・商品コード集約(_年度,_部署コード,_商品コード,_金額合計) :- findsum(_金額,( テーブル(_年度,_月,_部署コード,_商品コード,_金額)), _年度・部署コード・商品コード集約). 鍵ならびの生成(_鍵変数ならび,_述語,_鍵ならび) :- findsetof(_鍵変数ならび,_述語,_鍵ならび). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/12 # # 以下のようなテーブルがあるとします。 # [テーブル名:経費TBL] # 会社 , 部署 , 年度 , 月 , 経費 # ------------------------------- # AAA , AAA01 , 2009 , 1 , 10000 # AAA , AAA01 , 2009 , 1 , 20000 # AAA , AAA01 , 2009 , 2 , 30000 # AAA , AAA01 , 2009 , 3 , 40000 # BBB , AAA01 , 2009 , 4 , 50000 # BBB , AAA01 , 2010 , 1 , 60000 # CCC , AAA01 , 2010 , 1 , 70000 # CCC , AAA01 , 2010 , 1 , 80000 # # ここから以下のような、 # 会社別、部署別の集計データを作成したいとします。 # 会社 , 部署 , 200901経費計 , 200902経費計 , … , 201012経費計 # # この時、経費計列の条件指定はどうしたら良いのでしょうか? # # '会社別、部署別の集計データを作成したいとします。 会社 , 部署 , 200901経費計 , 200902経費計 , … , 2010122経費計 ' :- 見出し表示, findsetof([_会社,_部署],経費TBL(_会社,_部署,_,_,_),L1), append(_,[[_会社,_部署]]|R],L1), findall(_経費計,( 年度・月の生成(_年度,_月), findsum(_経費,( 経費TBL(_会社,_部署,_年度,_月,_経費)), _経費計)), _経費ならび), concat_atom(_経費ならび,',',_経費月別表示), write_formatted('%t,%t,%t\n',[_会社,_部署,_経費月別表示]), R = []. 年度・月の生成(2009,_月) :- for(1,_月,12). 年度・月の生成(2010,_月) :- for(1,_月,12). 見出し表示 :- write(' 会社 , 部署 '), 年度の生成(_年,_月), write_formatted_atom(S,', %4d%02d経費計 ',[_年,_月]), write(S), fail. 見出し表示 :- nl. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/8 # # よくある質問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によって文法がかなり違うので注意 # # 'HOGEをAもBもCも持っている、ID:01だけ取り出す'(L,_ID) :- findsetof(_ID,'TableName'(_ID,_)), 関係の割り算(_ID,L). 関係の割り算(_,[]):- !. 関係の割り算(_ID,[_HOGE|R]) :- 'TableName'(_ID,_HOGE), 関係の割り算(_ID,R). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/7 # # よくある質問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 # ; # 'Excelのピボットの様なデータを取得したい' :- findsetof(_data,table(_,_data),L1), findsetof(_key,table(_key,_data),L2), append(_,[_key|R],L2), findall(Count, count((append(_,[_data|_],L1),table(_key,_data)),Count), L3), concat_atom([_key|L3],',',S), write_formatted('%t\n',[S]), R = []. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1299305530/6 # # よくある質問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 # ; # 'TableName'(1,'2007-11-11',aaa). 'TableName'(2,'2007-11-11',bbb). 'TableName'(1,'2007-11-10',ccc). 'TableName'(3,'2007-11-12',ddd). 'TableName'(3,'2007-11-11',eee). 'TableName'(4,'2007-11-10',fff). 'TableName'(1,'2007-11-12',ggg). '各idに対して最新の1件だけ抽出する'(_ID,_DATE,_DATA) :- findsetof(_ID,'TableName'(_ID,_,_),L1), append(_,[_ID|_],L1), findmax([_DATE,_ID,_DATA],( 'TableName'(_ID,_DATE,_DATA)), [_DATE,_ID,_DATA]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/967 # # # ■DBMS名とバージョン # Firebird 1.03 # ■テーブルデータ (注文データベースのようなものです) # ・Main 主情報テーブルMIDがキー # MID HACCHUBI # 1 2011/03/01 # ・DETAIL 明細テーブルDIDがキー MID,IIDが参照キー # DID MID IID KOSU # 1  1  1  100 # 2  1  2  30 # ・ITEM 商品テーブルIIDがキー # IID NAMAE ZAIKO OPOINT BIKO # 1  HOGE  20  10   0 # 2  HUGA  50  5    1 # ■欲しい結果 # 2011/1/1から1/31の注文のあった各アイテムの個数(DETAIL.KOSU)の平均値が10以上の場合、 # 該当するアイテムの注文ライン(ITEM.OPOINT)に、その平均値を入れて更新。平均値が10未満の場合、 # ITEM.OPOINTに0を入れる。ただしアイテムの備考(ITEM.BIKO)が1の場合は、ITEM.OPOINTには # 空欄(NULL)にする。 # ■説明 # といいますか、上記の欲しい結果が全てなのですが、どう書いていいのかちょっと見当がつきません。 # 在庫の仕入れをする個数(ITEM.OPOINT)の設定をコンピュータにさせようとしているのですが・・・。 # 丸投げで申し訳ありませんが、どなたかお願いします。 '2011/1/1から1/31の注文のあった各アイテムの個数(DETAIL.KOSU)の平均値が10以上の場合、該当するアイテムの注文ライン(ITEM.OPOINT)に、その平均値を入れて更新。平均値が10未満の場合、ITEM.OPOINTに0を入れる。ただしアイテムの備考(ITEM.BIKO)が1の場合は、ITEM.OPOINTには空欄(NULL)にする' :- findsetof(_MID,( 'Main'(_MID,_HACCHUBI), _HACCHUBI @>= '20110101', _HACCHUBI @=< '20110131'), L1), findsetof(_IID,( 'DETAIL'(_DID,_MID,_IID,_KOSU), append(_,[_MID|_],L1)), L2), append(_,[IID|R],L2), findavg(_KOSU,( 'DETAIL'(_DID,_MID,_IID,_KOSU), append(_,[_MID|_],L1)), AVG), 'ITEM更新'(IID,AVG), R = []. 'ITEM更新'(IID,AVG) :- retract('ITEM'(_IID,_NAMAE,_ZAIKO,_OPOINT,'1')), assertz('ITEM'(_IID,_NAMAE,_ZAIKO,'',_BIKO)),!. 'ITEM更新'(IID,AVG) :- AVG >= 10, write_formatted_atom(S,'%t',[AVG]), retract('ITEM'(_IID,_NAMAE,_ZAIKO,_OPOINT,_BIKO)), assertz('ITEM'(_IID,_NAMAE,_ZAIKO,S,_BIKO)),!. 'ITEM更新'(IID,AVG) :- AVG < 10, retract('ITEM'(_IID,_NAMAE,_ZAIKO,_,_BIKO)), assertz('ITEM'(_IID,_NAMAE,_ZAIKO,'0',_BIKO)),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1296387672/580 # # [1]授業単元:プログラミング # [2]問題文 # 担当者名が"end"になる迄、担当者名と売上を入力する。売上合計を求める。 # [3]環境 #  [3.1]OS:Windows #  [3.2]コンパイラ名 Borland C++ compiler 5.5 #  [3.3]言語:C # [4]期限:無期限 # '担当者名が"end"になる迄、担当者名と売上を入力する。売上合計を求める。' :- abolish(担当者別売上/2), 担当者名と売上を入力する(_担当者名,_売上), '担当者名が"end"になる迄、担当者名と売上を入力する。売上合計を求める。'(_担当者名,_売上),!. '担当者名が"end"になる迄、担当者名と売上を入力する。売上合計を求める。' :- 担当者別売上合計の表示, 売上合計の表示. 担当者名と売上を入力する(_担当者名,_売上) :- write('担当者名を入力してください : '), get_line(_担当者名), \+(_担当者名 = 'END'), write('売上を入力してください : '), get_integer(_売上),!. '担当者名が"end"になる迄、担当者名と売上を入力する。売上合計を求める。'(_担当者名,売上) :- assertz(担当者別売上(_担当者名,_売上)), 担当者名と売上を入力する(_担当者名2,_売上2), '担当者名が"end"になる迄、担当者名と売上を入力する。売上合計を求める。'(_担当者名2,売上2). 担当者別売上合計の表示 :- findsetof(_担当者,( 担当者別売上(_担当者,_)), _担当者ならび), append(_,[_担当者|R],_担当者ならび), findsum(_売上,担当者別売上(_担当者,_売上),_担当者別売上合計), wr('担当者:%t,売上合計:%t\n',[_担当者,_担当者別売上合計]), R = []. 売上合計の表示 :- findsum(_売上,担当者別売上(_,_売上),_売上合計), write_formatted('総売上合計は %t です。\n',[_売上合計]). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/879 # # ・DBMS名とバージョン # oracle9i / 10g # ・テーブルデータ # 部署ID 大分類 中分類 小分類 予算 # -------+------+-------+------+--- # 01 01 01 01 2500 # 01 02 01 01 1000 # 01 02 02 02 100 # 02 01 01 01 100 # 02 01 02 02 0 # 02 02 02 02 1000 # 02 03 01 01 0 # 03 01 01 01 500 # # ・欲しい結果 # 上のテーブルの時、 # (大分類=01and予算>50) and (大分類=02and予算<2000) # の部署IDを取得したい。 # ・説明 # とりたい結果は01,02ですが上のSQLを # そのまま書くと当然結果はnullですし、 # 括弧の間のandをorにすると03も取得されてしまいます。 # なにか良い方法はないでしょうか? # # テーブルデータ('01','01','01','01',2500). テーブルデータ('01','02','01','01',1000). テーブルデータ('01','02','02','02',100). テーブルデータ('02','01','01','01',100). テーブルデータ('02','01','02','02',0). テーブルデータ('02','02','02','02',1000). テーブルデータ('02','03','01','01',0). テーブルデータ('03','01','01','01',500). '(大分類=01and予算>50) and (大分類=02and予算<2000)の部署IDを取得したい'(_部署ID) :- findsetof([_部署ID,_大分類],( テーブルデータ(_部署ID,_大分類,_,_,_)), L), findall([_部署ID,_大分類,_予算計],( append(_,[[_部署ID,_大分類]|_],L)), findsum(_予算,( テーブルデータ(_部署ID,_大分類,_,_,_予算)), _予算計)), _部署ID・大分類・予算計ならび), append(_,[[_部署ID,'01',_予算計_1]|_],_部署ID・大分類・予算計ならび), _予算計_1 > 50, append(_,[[_部署ID,'02',_予算計_2]|_],_部署ID・大分類・予算計ならび), _予算計_2 < 2000. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/873 # # ・DBバージョン # MySQL5.0.77 # # id|_regDate_| # --+----------+ # 1 |2010-10-10| # 2 |2010-10-10| # 3 |2010-10-10| # 4 |2010-10-11| # 5 |2010-10-11| # 6 |2010-10-11| # 7 |2010-10-11| # 8 |2010-10-12| # 9 |2010-10-12| # 10|2010-10-12| # 11|2010-10-12| # # ・欲しい結果 # 何件レコードがあったかを日別に出力したい。 # # 例として # _regDate__|件数 # ----------+- # 2010-10-10|3 # 2010-10-11|4 # 2010-10-12|4 # # こうなってるとうれしいです。 # # ・説明 # 自前でクリックカウンターを作っております。 # ほかにカラムとしてユーザーエージェントやリモートホストのアドレスを設置してありまして # 日別に集計して見れるようにしたいと思ったのですが、PHPでループを書いて出力するより # SQLの問い合わせ段階で、上記のように整形できないかなと思いました。 # # よろしくお願いいたします。 # # 何件レコードがあったかを日別に出力する :- write('-- 日付 --|件数\n'), findsetof(_日付,テーブル(_id,_日付),L), append(_,[_日付|R],L), count(テーブル(_id,_日付),_件数), write_formatted('%t|%t\n',[_日付,_件数]), R = []. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/846 # # ・DBMS名とバージョン #  Microsoft Access2000 # # ・テーブルデータ # 【ITEM_COUNT】 # item_id | year | month | count # --------------------------- # 00001  | 2010 |   1 |  150 # 00001  | 2010 |   1 |  400 # 00001  | 2010 |   2 |   20 #   (中略) # 00001  | 2010 |  11 |  120 # 00001  | 2010 |  11 |   50 # 00001  | 2010 |  11 |  200 # 00001  | 2010 |  12 |   30 # 00001  | 2011 |   1 |  500 # 00001  | 2011 |   1 |  100 # 00002  | 2010 |   1 |   10 # 00002  | 2010 |   2 |   30 # 00002  | 2010 |   2 |  100 #   (後略) # ※同じid, year, monthのデータが複数存在します。 # # # ・欲しい結果 # item_id | 1月 | 2月 | … | 11月 | 12月 | 13月 # -------------------------------------------- # 00001  | 550 |  20 | … | 370 |  30 | 610 # 00002  |  10 | 130 | … | (後略) # # ※2010/1〜2011/1の13ヶ月間を1月〜13月として(2011/1を13月として)それぞれ集計を求めたい # # # ・説明 # 現状は、 # ------------------------------------ # SELECT #  year, item_id # FROM #  ITEM_COUNT # WHERE #  year=2010 # GROUP BY #  item_id, year # PIVOT #  Format(month,"#0月") In ("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"); # ------------------------------------ # 上のクエリを「集計1」、WHERE句を"year=2011"に変更したものを「集計2」とし、 # 次のクエリで結果を求めています。 # ------------------------------------ # SELECT #  集計1.item_id, 集計1.[1月], 集計1.[2月], … , 集計1.[12月],集計2.[1月] AS 13月 # FROM #  集計1 LEFT JOIN 集計2 ON 集計1.[item_id] = 集計2.[item_id] # ------------------------------------ # # しかしこれだと2011/1にのみデータがあるitem_idが集計から外れてしまいます。 # これを回避するにはどのように直したら良いでしょうか。 # # 年度を俣いで月合計を表示する :- findsetof([_item_id],( 'ITEM_COUNT'(_item_id,_year,_month,_count)), L1), findall([_item_id,_合計回数ならび],( append(_,[_item_id|_],L1), '2010年集計'(_2010年counts), '2011年集計'(_2011年counts), append(_2010年counts,_2011年counts,_合計回数ならび)), _集計ならび), 見出し表示, append(_,[[_itemp_id,_合計回数ならび]|R],_集計ならび), write_formatted(' %3d | %3d | %3d | %3d | %3d | %3d | %3d | %3d | %3d | %3d | %3d | %3d | %3d\n',_合計回数ならび), R = []. 見出し表示 :- append(_,[_月|R],['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']), write_formatted(' %3s |',[_月]), R = [], write(' 13月\n'),!. '2010年集計'(_item_id,2010,_month,_合計回数) :- for(1,_month,12), findsum(_count,'ITEM_COUNT'(_item_id,2000,_month,_count),_合計回数). '2011年集計'(_item_id,2011,_month,_合計回数) :- findsum(_count,'ITEM_COUNT'(_item_id,2011,1,_count),_合計回数). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/815 # # こんなレコードが格納されているとします。 # ID,NO # 100,1 # 102,2 # 101,3 # 200,1 # 201,2 # 202,3 # この場合、IDを100番台、200番台でグルーピングして、各グループ毎にNO順にSELECTで出力しようとした場合、どのような条件にすればよいでしょうか? # IDはこの例では3桁ですが、実際には6桁程あり、出来ればWHERE句で数字を入れて指定するような事はせずに並び替えが出来ると嬉しいです。 # 要は、レコードが増えてグループが増えたりしても、条件を変えずに並び替えが出来るようなものが良いのですが、可能でしょうか? # 宜しくご教示願います。 # # 'IDを100番台、200番台でグルーピングして、各グループ毎にNO順に出力する' :- findsetof(_ID,( テーブル(_ID,_NO), _ID_1 is (_ID // 100) + 1), _IDグループならび), findall(LL1,( append(_,[_ID_1|_],_IDグループならび), findall([_NO,_ID],( テーブル(_ID,_NO), _ID_1 is (_ID // 100) + 1), LL1)), LL2), 各グループ毎にNO順に出力する(LL2). 各グループ毎にNO順に出力する(LL) :- append(_,[L1|R1],LL), 整列(L1,L2), append(_,[[_NO,_ID]|R2],L2), write_formatted('%t,%t\n',[_ID,_NO]), R2 = [], R1 = [],!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1294061094/666 # # [1] 授業単元: # [2] 問題文: http://ime.nu/ux.getuploader.com/sanada1678/download/17/%E3%82%B3%E3%83%94%E3%83%BC+%EF%BD%9E+%E8%AA%B2%E9%A1%8C.csv # # ある駐車場が昼間20分100円の料金で駐車場を貸しています。 # 左のデータは入出庫のデータです。 # 駐車時間の長さの分類はおもに # 20分,40分,1時間,2時間,6時間,12時間,24時間以上 # です。これをもとに次の問題を解決せよ。 # # 毎時00分時点での(つまり1時間ごとの) # 駐車している駐車台数を自動計算するように表計算のプログラムを作成したい。 # # 1.1時間の間(たとえばその日の13時から14時)に入場してきた車の台数 #   その時間内に清算して出場して行った台数を自動計算するように表計算の #   プログラムを作成せよ。その結果として、00分時点での駐車台数が自動計算できる #   ようにプログラムを作成せよ。 # # 2.一定期間内(例えば1日や一週間と特定して)での #   駐車時間の長さで分類した台数 #   たとえば 30分以内,1H,2H,6H,12H,24H以上 #   が自動計算できるようにプログラムを作成せよ。 # # 3.とりあえず最初に駐車していた台数を0台として表を作成せよ。 #   それが出来たら最初に駐車していた台数を任意に設定することで #   その後の駐車している台数を自動計算できるように表を作成せよ。 # # 11月、12月などのデータを入力しても瞬時に計算できるようにしておく。 # 夜間の駐車料金などもデータから推測せよ。 # # 2010/10/31 20:38,2010/10/31 23:24,,300,300,,,,,,,,, # 2010/10/31 10:47,2010/10/31 22:12,,600,600,,,,,,,,, # 2010/10/31 12:25,2010/10/31 22:06,,600,600,,,,,,,,, # 2010/10/31 19:13,2010/10/31 21:52,,500,500,,,,,,,,, # 2010/10/31 18:49,2010/10/31 21:50,,600,600,,,,,,,,, # 2010/10/31 15:30,2010/10/31 21:45,,600,600,,,,,,,,, # 2010/10/31 10:06,2010/10/31 21:37,,600,600,,,,,,,,, # 2010/10/30 21:57,2010/10/31 21:32,,600,600,,,,,,,,, # 2010/10/31 13:02,2010/10/31 21:29,,600,600,,,,,,,,, # 2010/10/31 20:25,2010/10/31 21:16,,100,100,,,,,,,,, # 2010/10/30 21:19,2010/10/31 21:02,,600,600,,,20,,,,,, # 2010/10/31 9:43,2010/10/31 20:53,,600,600,,,,,,,,, # 2010/10/31 17:45,2010/10/31 20:43,,600,600,,,,,,,,, # 2010/10/31 18:38,2010/10/31 20:38,,600,600,,,00,,,,,, # 2010/10/29 6:53,2010/10/31 20:23,,1800,1800,,,,,,,,, # 2010/10/31 8:04,2010/10/31 19:53,,600,600,,,,,,,,, # 2010/10/31 5:32,2010/10/31 19:25,,600,600,,,,,,,,, # 2010/10/31 12:19,2010/10/31 19:15,,600,600,,,,,,,,, # 2010/10/31 5:53,2010/10/31 19:09,,600,600,,,00,,,,,, /* 'ある駐車場が昼間20分100円の料金で駐車場を貸しています。'. */ '左のデータは入出庫のデータです。'(_入出庫データファイル,_入出庫データならび) :- get_split_lines(_入出庫データファイル,[','],_入出庫データならび). /* '駐車時間の長さの分類はおもに20分,40分,1時間,2時間,6時間,12時間,24時間以上です。'(_駐車開始時刻,_駐車終了時刻,_駐車時間) :- 駐車時間は同一日である(_駐車開始時刻,_駐車終了時刻). '駐車時間の長さの分類はおもに20分,40分,1時間,2時間,6時間,12時間,24時間以上です。'(_駐車開始時刻,_駐車終了時刻,_駐車時間) :- \+(駐車時間は同一日である(_駐車開始時刻,_駐車終了時刻)). */ '毎時00分時点での(つまり1時間ごとの)駐車している駐車台数を自動計算する'(_毎時00分時点での駐車している駐車台数ならび) :- '左のデータは入出庫のデータです。'(_入出庫データファイル,_入出庫データならび), '毎時00分時点での(つまり1時間ごとの)駐車している駐車台数を自動計算するように表計算のプログラムを作成したい。'(_入出庫データならび,_毎時00分時点での駐車している駐車台数ならび). '毎時00分時点での(つまり1時間ごとの)駐車している駐車台数を自動計算する'(LL,LL2) :- findsetof([_年,_月,_日,_時],( append(_,[L|R1],LL), 発生した年・月・日・時(L,_年,_月,_日,_時)), LL1), findall([_年,_月,_日,_時,_駐車台数],( append(_,[[_年,_月,_日,_時]|_],LL1), '毎時00分時点での(つまり1時間ごとの)駐車している駐車台数'(LL,_年,_月,_日,_時,_駐車台数)), LL2). 発生した年・月・日・時([_時刻|_],_年,_月,_日,_時) :- split(_時刻,[' ','/',':'],[_年,_月,_日,_時|_]). 発生した年・月・日・時([_,_時刻|_],_年,_月,_日,_時) :- split(_時刻,[' ','/',':'],[_年,_月,_日,_時|_]). '毎時00分時点での(つまり1時間ごとの)駐車している駐車台数'(LL,_年,_月,_日,_時,_駐車台数) :- count(( member([A,B|_],LL), split(A,['/',' ',':'],LA), split(B,['/',' ',':'],LB), LA @=< [_年,_月,_日,_時,0], LB @>= [_年,_月,_日,_時,0]), _駐車台数),!. '1時間の間(たとえばその日の13時から14時)に入場してきた車の台数その時間内に清算して出場して行った台数を自動計算する'(LL,_年,_月,_日,_時,_入場車数,_出場車数) :- count(( member([A|_],LL), split(A,['/',' ',':'],LA), LA @>= [_年,_月,_日,_時,0], LA @=< [_年,_月,_日,_時,59]), _入場車数), count(( member([_,A|_],LL), split(A,['/',' ',':'],LA), LA @>= [_年,_月,_日,_時,0], LA @=< [_年,_月,_日,_時,59]), _出場車数),!. '一定期間内(例えば1日や一週間と特定して)での駐車時間の長さで分類した台数たとえば30分以内,1H,2H,6H,12H,24H以上を自動計算する'(LL,_時刻下限,_時刻上限,_30分以内,_1H,_2H,_6H,_12H,_24H,_24H以上) :- '一定期間内(例えば1日や一週間と特定して)での駐車時間の長さで分類した台数たとえば30分以内,1H,2H,6H,12H,24H以上を自動計算する'(LL,_時刻下限,_時刻上限,0,0,0,0,0,0,0,_30分以内,_1H,_2H,_6H,_12H,_24H,_24H以上). '一定期間内(例えば1日や一週間と特定して)での駐車時間の長さで分類した台数たとえば30分以内,1H,2H,6H,12H,24H以上を自動計算する'([],_時刻下限,_時刻上限,_30分以内,_1H,_2H,_6H,_12H,_24H,_24H以上,_30分以内,_1H,_2H,_6H,_12H,_24H,_24H以上) :- !. '一定期間内(例えば1日や一週間と特定して)での駐車時間の長さで分類した台数たとえば30分以内,1H,2H,6H,12H,24H以上を自動計算する'([[_入場時刻,_出場時刻|_]|R],_時刻下限,_時刻上限,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1,_30分以内,_1H,_2H,_6H,_12H,_24H,_24H以上) :- split(_入場時刻,[' ','/',':'],[_年_1,_月_1,_日_1,_時_1,_分_1]), split(_出場時刻,[' ','/',':'],[_年_2,_月_2,_日_2,_時_2,_分_2]), [_年_1,_月_1,_日_1,_時_1,_分_1] @>= _時刻下限, [_年_2,_月_2,_日_2,_時_2,_分_2] @=< _時刻上限, 入場時刻と出場時刻の時間差分単位(_入場時刻,_出場時刻,_時間差分単位), 時間差単位(_時間差分単位,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1,_30分以内_2,_2H_2,_2H_2,_6H_2,_22H_2,_24H_2,_24H以上_2), '一定期間内(例えば1日や一週間と特定して)での駐車時間の長さで分類した台数たとえば30分以内,1H,2H,6H,12H,24H以上を自動計算する'(R,_時刻下限,_時刻上限,_30分以内_2,_1H_2,_2H_2,_6H_2,_12H_2,_24H_2,_24H以上_2,_30分以内,_1H,_2H,_6H,_12H,_24H,_24H以上). '一定期間内(例えば1日や一週間と特定して)での駐車時間の長さで分類した台数たとえば30分以内,1H,2H,6H,12H,24H以上を自動計算する'([_|R],_時刻下限,_時刻上限,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1,_30分以内,_1H,_2H,_6H,_12H,_24H,_24H以上) :- '一定期間内(例えば1日や一週間と特定して)での駐車時間の長さで分類した台数たとえば30分以内,1H,2H,6H,12H,24H以上を自動計算する'(R,_時刻下限,_時刻上限,_30分以内_1,_1H_1,_1H_1,_6H_1,_12H_1,_14H_1,_14H以上_1,_30分以内,_1H,_1H,_6H,_12H,_14H,_14H以上). 時間差単位(_分,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1,_30分以内_2,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1) :- _分 =< 30, _30分以内_2 is _30分以内_1 + 1,!. 時間差単位(_分,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1,_30分以内_1,_1H_2,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1) :- _分 >= 30,_分 < 60, _1H_2 is _1H_1 + 1,!. 時間差単位(_分,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1,_30分以内_1,_1H_1,_2H_2,_6H_1,_12H_1,_24H_1,_24H以上_1) :- _分 >= 60,_分 < 120, _2H_2 is _2H_1 + 1,!. 時間差単位(_分,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1,_30分以内_1,_1H_1,_2H_1,_6H_2,_12H_1,_24H_1,_24H以上_1) :- _分 >= 120,_分 < 360, _6H_2 is _6H_1 + 1,!. 時間差単位(_分,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_2,_24H_1,_24H以上_1) :- _分 >= 360,_分 < 720, _12H_2 is _12H_1 + 1,!. 時間差単位(_分,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_2,_24H以上_1) :- _分 >= 720,_分 < 1440, _24H_2 is _24H_1 + 1,!. 時間差単位(_分,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_1,_30分以内_1,_1H_1,_2H_1,_6H_1,_12H_1,_24H_1,_24H以上_2) :- _分 >= 1440, _24H以上_2 is _24H以上_1 + 1,!. 'とりあえず最初に駐車していた台数を0台として表を作成せよ。それが出来たら最初に駐車していた台数を任意に設定することでその後の駐車している台数を自動計算できるように表を作成せよ。'. '11月、12月などのデータを入力しても瞬時に計算できるようにしておく。夜間の駐車料金などもデータから推測せよ。'. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 入場時刻と出場時刻の時間差分単位(_入場時刻,_出場時刻,_時間差分単位) :- atom(_入場時刻), atom(_出場時刻), split(_入場時刻,['/',' ',':'],[_年_1,_月_1,_日_1,_時_1,_分_1]), split(_出場時刻,['/',' ',':'],[_年_2,_月_2,_日_2,_時_2,_分_2]), 出場時刻と入場時刻の時間差分単位([_年_1,_月_1,_日_1,_時_1,_分_1],[_年_2,_月_2,_日_2,_時_2,_分_2],_時間差分単位). 入場時刻と出場時刻の時間差分単位([_年,_月,_日,_時,_分_1],[_年,_月,_日,_時,_分_2],_時間差分単位) :- _時間差分単位 is _分2 - _分1,!. 入場時刻と出場時刻の時間差分単位([_年,_月,_日,_時_1,_分_1],[_年,_月,_日,_時_2,_分_2],_時間差分単位) :- _時間差分単位 is (60 * _時_2 + _分_2) - (60 * _時_1 + _分1),!. 入場時刻と出場時刻の時間差分単位([_年,_月,_日_1,_時_1,_分_1],[_年,_月,_日_2,_時_2,_分_2],_時間差分単位) :- _時間差分単位 is (1440 * _日_2 + 60 * _時_2 + _分_2) - (1440 * _日_1 + 60 * _時_1 + _分1),!. 入場時刻と出場時刻の時間差分単位([_年,_月_1,_日_1,_時_1,_分_1],[_年,_月_2,_日_2,_時_2,_分_2],_時間差分単位) :- _月_2_1 is _月_2 - 1, findsum(_月日数,( for(_月_1,_月,_月_2_1), 月日数(_年_1,_月,_月日数)), _月日数合計の一), _月日数合計 is truncate(_月日数合計の一), _時間差分単位 is (1440 * _月日数合計 + 1440 * _日_2 + 60 * _時_2 + _分_2) - (1440 * _日_1 + 60 * _時_1 + _分_1),!. 入場時刻と出場時刻の時間差分単位([_年_1,_月_1,_日_1,_時_1,_分_1],[_年_2,_月_2,_日_2,_時_2,_分_2],_時間差分単位) :- _年_2_1 is _年_2 - 1, findsum(_年日数,( for(_年_1,_年,_年_2_1), 年日数(_年,_年日数)), _年日数合計の一), _年日数合計 is truncate(_年日数合計の一), _月_1_1 is _月_1 - 1, findsum(_月日数,( for(0,_月,_月_1_1), 月日数(_年_1,_月,_月日数)), _月日数合計の一), _月日数合計_1 is truncate(_月日数合計の一), _月_2_1 is _月_2 - 1, findsum(_月日数,( for(0,_月,_月_2_1), 月日数(_年_2,_月,_月日数)), _月日数合計の二), _月日数合計_2 is truncate(_月日数合計の二), _時間差分単位 is (1440 * _年日数の合計 + 1440 * _月日数合計_2 + 1440 * _日_2 + 60 * _時_2 + _分_2) - (1440 * _月日数合計_1 + 1440 * _日_1 + 60 * _時_1 + _分_1),!. 年日数(_年,366) :- うるう年(_年),!. 年日数(_年,365). 月日数(_年,2,29) :- うるう年(_年),!. 月日数(_年,2,29) :- \+(うるう年(_年)),!. 月日数(_年,_月,31) :- append(_,[_月|_],[1,3,5,7,8,10,12]),!. 月日数(_年,_月,30) :- append(_,[_月|_],[4,6,9,11]),!. 月日数(_,0,0). うるう年(_年) :- 0 is _年 mod 400,!. うるう年(_年) :- 0 is _年 mod 100,!, fail . うるう年(_年) :- 0 is _年 mod 4,!. うるう年(_年) :- \+(0 is _年 mod 4), fail. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1268979408/332 # # ●環境 # vb.net # # ●したいこと # 3文字以上の繰り返し表現を抽出 # # ●サンプル # 例文1)死にたい死にたい死にたい死にたい死にたい # 結果1)死にたい # # ●したいこと # 2箇所以上出現する3文字以上の文字列 # # 例文2)筋肉バスターと阿修羅バスター # 結果2)バスター # # # ってのを正規表現でやるのは無理でしょうか・・・ # '重複しない3文字以上の繰り返し表現を抽出'(_文字列,_重複しない3文字以上の繰り返し表現ならび) :- findsetof(_3文字以上の繰り返し表現,( '3文字以上の繰り返し表現を抽出'(_文字列,_3文字以上の繰り返し表現), _重複しない3文字以上の繰り返し表現ならび). '3文字以上の繰り返し表現を抽出'(_文字列,_3文字以上の繰り返し表現) :- sub_atom(_文字列,_開始点,_長さ,_残り長さ,[_3文字以上の繰り返し表現|R]), _長さ >= 3, _開始点2 is _開始点 + _長さ, sub_atom(_文字列,_開始点2,_長さ,_残り長さ2,_3文字以上の繰り返し表現). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/753 # # ../test/read.cgi/db/1274791771/4のような状況で、 # よくある質問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 # # # 各IDごとにランダムで2件抽出して、そのDATEを # 現在の日時に更新するにはどうすればよいでしょうか? # 各IDごとにランダムで2件抽出して、そのDATEを現在の日時に更新する :- findsetof(_ID,'TableName'(_ID,_DATE,_DATA),_IDならび), append(_,[_ID|R],_IDならび), findall([_ID,_DATE,_DATA],( 'TableName'(_ID,_DATE,_DATA)), L1), length(L1,_要素数), ランダムに2件抽出して(_要素数,L1,L2), 現在の日時に更新する(L2), R = []. ランダムに2件抽出して(0,[],[]) :- !. ランダムに2件抽出して(1,LL,LL) :- !. ランダムに2件抽出して(_要素数,L1,[_1,_2]) :- Nth1 is (random mod _要素数) + 1, list_nth(Nth1,L1,_1), repeat, Nth2 is (random mod _要素数) + 1, \+(Nth1 = Nth2), list_nth(Nth2,L1,_2),!. 現在の日時に更新する([[_ID,_DATE,_DATA]|R1]) :- 現在の日時(_現在の日時), findall([_ID,_DATE2,_DATA2], retract('TableName'(_ID,_DATE2,_DATA2)), L1), 現在の日時に更新する(_現在の日時,[[_ID,_DATE,_DATA]|R1],L1). 現在の日時に更新する(_現在の日時,[],[]) :- !. 現在の日時に更新する(_現在の日時,[],L) :- append(_,[[_ID,_DATE,_DATA]|R],L), assertz('TableName'(_ID,_DATE,_DATA)), R = [],!. 現在の日時に更新する(_現在の日時,[[_ID,_DATE,_DATA]|R1],[[_ID,_DATE,_DATA]|R2]) :- assertz('TableName'(_ID,_現在の日時,_DATA)), 現在の日時に更新する(_現在の日時,R1,R2),!. 現在の日時に更新する(_現在の日時,[[_ID,_DATE,_DATA]|R1],[[_ID,_DATE2,_DATA1]|R2]) :- assertz('TableName'(_ID,_DATE2,_DATA2)), 現在の日時に更新する(_現在の日時,[[_ID,_DATE,_DATA]|R1],R2),!. % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/471 # # 【質問テンプレ】 # ・DBMS名とバージョン: SQLite 3 # ・テーブルデータ:長いため下記に記載 # ・欲しい結果:RSSリーダ(brief)のデータ(*.sqlite)から特定の記事データを削除したいです。 # ・説明:長いため下記に記載 # # ●テーブルデータ # ======================================================================================================================= # ■entries #  | id | feedID | primaryHash | secondaryHash | providerID | entryURL | date | read | updated | starred | deleted | bookmarkID | # ----------------------------------------------------------------------------------------------------------------------- # ■entries_text #  | title | content | authors | tags | # ----------------------------------------------------------------------------------------------------------------------- # ■entries_text_content #  | docid | c0title | c1content | c2authors | c3tags | # ----------------------------------------------------------------------------------------------------------------------- # ■sqlite_sequence #  | name | seq | # ======================================================================================================================= # # 1.【entries】テーブルの[deleted]フィールドが「 2 」の場合に、そのレコードを削除。 # # 2.同時に、【entries_text_content】テーブルの[docid]フィールドが、1.で削除した #   [id]フィールドと同じ値のレコードも削除。 # # 3.更に同時に、【entries_textテーブル】から、1.で削除した[idフィールド]の値(数字)と #   同じレコード番号のレコードを削除。 ※idフィールドがない為 # # 4.その後、下記のフィールドの値を、1・2・3〜とリナンバリングしたい。 #   【entries】テーブルの[id]フィールド #   【entries_text_content】テーブルの[docid]フィールド # # 5.そして、1.2.3.の三つのテーブルのレコード数がどれも同じ数だけあるか確認。 # # 6.最後に、【sqlite_sequence】テーブルの[seq]フィールドに5.で確認したレコード数を #   設定したい。 # # お手数ですが、以上よろしくお願いします。 # # '1.【entries】テーブルの[deleted]フィールドが「 2 」の場合に、そのレコードを削除' :- findsetof(_id,( entries(_id,_feedID,_primaryHash,_secondaryHash,_providerID,_entryURL,_date,_read,_updated,_starred,_deleted,_bookmarkID)), _deleted = '2'), L1), retract_all(entries(_id,_feedID,_primaryHash,_secondaryHash,_providerID,_entryURL,_date,_read,_updated,_starred,'2',_bookmarkID)), findsetof(_docid,( member(_id,L1), entries_text_contents(_docid,_c0title,_c1content,_c2authors,_c3tags)), _docid = _id), L2), '2.同時に、【entries_text_content】テーブルの[docid]フィールドが、1.で削除した[id]フィールドと同じ値のレコードも削除。'(L2), '3.更に同時に、【entries_textテーブル】から、1.で削除した[idフィールド]の値(数字)と同じレコード番号のレコードを削除。'(L1),!. '2.同時に、【entries_text_content】テーブルの[docid]フィールドが、1.で削除した[id]フィールドと同じ値のレコードも削除。'(L2) :- member(_docid,L2), retract_all(entries_text_contents(_docid,_c0title,_c1content,_c2authors,_c3tags)),!. '3.更に同時に、【entries_textテーブル】から、1.で削除した[idフィールド]の値(数字)と同じレコード番号のレコードを削除。'(L1) :- append(_,[Nth|R],L1), 節の定義位置指定による節の削除(L2,Nth), R = [],!. '3.更に同時に、【entries_textテーブル】から、1.で削除した[idフィールド]の値(数字)と同じレコード番号のレコードを削除。'(_). 節の定義位置指定による節の削除(L2,Nth) :- findall((Head :- Body),( clause(entries_text(_title,_content,_authors,_tags),Head,Body)), L2), list_nth(Nth,L2,P), retract(P),!. '4.その後、下記のフィールドの値を、1・2・3〜とリナンバリングしたい。 【entries】テーブルの[id]フィールド 【entries_text_content】テーブルの[docid]フィールド' :- findall(entries(_id,_feedID,_primaryHash,_secondaryHash,_providerID,_entryURL,_date,_read,_updated,_starred,_deleted,_bookmarkID),( retract(entries(_id,_feedID,_primaryHash,_secondaryHash,_providerID,_entryURL,_date,_read,_updated,_starred,_deleted,_bookmarkID))), L1), append(L01,[entries(_,_feedID,_primaryHash,_secondaryHash,_providerID,_entryURL,_date,_read,_updated,_starred,_deleted,_bookmarkID)|R1],L1), length([_|L0],Nth1), assertz(entries(Nth1,_feedID,_primaryHash,_secondaryHash,_providerID,_entryURL,_date,_read,_updated,_starred,_deleted,_bookmarkID)), R1 = [], findall(entries_text_contents(_,_c0title,_c1content,_c2authors,_c3tags),( retract(entries_text_contents(_docid,_c0title,_c1content,_c2authors,_c3tags))), L2), append(L02,[entries_text_contents(_,_c0title,_c1content,_c2authors,_c3tags)|R2],L2), length([_|L02],Nth2), assertz(entries_text_contents(Nth2,_c0title,_c1content,_c2authors,_c3tags)), R2 = [],!. '5.そして、1.2.3.の三つのテーブルのレコード数がどれも同じ数だけあるか確認。'(Count) :- count(entries(_id,_feedID,_primaryHash,_secondaryHash,_providerID,_entryURL,_date,_read,_updated,_starred,_deleted,_bookmarkID),Count), count(entries_text_contents(_docid,_c0title,_c1content,_c2authors,_c3tags),Count), count(entries_text(_title,_content,_authors,_tags),Count). '6.最後に、【sqlite_sequence】テーブルの[seq]フィールドに5.で確認したレコード数を設定したい。'(Count) :- retract(sqlite_sequence(_name,_seq)), assertz(sqlite_sequence(_name,Count),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1291471791/670 # # [1]授業単元:プログラミング演習 # [2]問題文 # 料理のデータベースを作成し、複数のデータの中からカロリーが最大と最小の料理の全データを出力するプログラムを作成せよ # # [3] # [3.1]Windows # [3.2]Visual Studio 2010 # [3.3]C # [4]12/20 # [5]各料理のデータは「番号、名前、カロリー」 #   料理とカロリーの値は適当でも可(ラーメン 10kcalとか) # # よろしくお願いします # # 食品のカロリー('カップ麺(ラーメン)',448). 食品のカロリー('クロワッサン',448). 食品のカロリー('インスタントラーメン',445). 食品のカロリー('カップ焼きそば',436). 食品のカロリー('デニッシュパン',396). 食品のカロリー('焼きふ',385). 食品のカロリー('コーンフレーク',381). 食品のカロリー('オートミール',380). 食品のカロリー('スパゲティ(乾麺)',378). 食品のカロリー('マカロニ(乾麺)',378). 食品のカロリー('ビーフン(乾麺)',377). 食品のカロリー('パン粉',373). 食品のカロリー('白玉粉',369). 食品のカロリー('小麦粉(薄力粉)',368). 食品のカロリー('小麦粉(中力粉)',368). 食品のカロリー('小麦粉(強力粉)',366). 食品のカロリー('コーンフラワー',363). 食品のカロリー('コーンミール',363). 食品のカロリー('上新粉',362). 食品のカロリー('はと麦',360). 食品のカロリー('アマランサス',358). 食品のカロリー('そうめん(乾)',356). 食品のカロリー('コーングリッツ',355). 食品のカロリー('とうもろこし(玄穀)',350). 食品のカロリー('てんぷら粉',349). 食品のカロリー('大麦(押麦)',340). 食品のカロリー('ロールパン',316). 食品のカロリー('チョココルネ',308). 食品のカロリー('クリームパン',305). 食品のカロリー('しゅうまいの皮',295). 食品のカロリー('春巻の皮',295). 食品のカロリー('餃子の皮',291). 食品のカロリー('あんまん',281). 食品のカロリー('あんぱん',280). 食品のカロリー('フランスパン',279). 食品のカロリー('ぶどうパン',269). 食品のカロリー('ピザクラスト',268). 食品のカロリー('コッペパン',265). 食品のカロリー('食パン',264). 食品のカロリー('ライ麦パン',264). 食品のカロリー('ナン',262). 食品のカロリー('ホットケーキ',261). 食品のカロリー('肉まん',251). 食品のカロリー('もち',235). 食品のカロリー('イングリッシュマフィン',228). 食品のカロリー('中華めん(蒸し)',198). 食品のカロリー('おこわ(赤飯)',189). 食品のカロリー('ごはん(精白米)',168). 食品のカロリー('ごはん(七分つき米)',168). 食品のカロリー('ごはん(はいが精米)',167). 食品のカロリー('ごはん(玄米)',165). 食品のカロリー('中華めん(ゆで)',149). 食品のカロリー('そば(ゆで)',132). 食品のカロリー('うどん(ゆで)',105). 食品のカロリー('フライドポテト',388). 食品のカロリー('マッシュポテト(乾)',357). 食品のカロリー('タピオカ(乾)',351). 食品のカロリー('さつまいも',163). 食品のカロリー('くずきり(ゆで)',135). 食品のカロリー('やまといも',123). 食品のカロリー('じゃがいも',73). 食品のカロリー('ながいも',65). 食品のカロリー('さといも',59). 食品のカロリー('しらたき',6). 食品のカロリー('こんにゃく',5). 食品のカロリー('凍り豆腐(乾)',529). 食品のカロリー('フライビーンズ',472). 食品のカロリー('きな粉',437). 食品のカロリー('ひよこ豆フライ',419). 食品のカロリー('だいず(乾)',417). 食品のカロリー('油揚げ',386). 食品のカロリー('えんどう豆(塩豆)',364). 食品のカロリー('はるさめ(緑豆・乾)',345). 食品のカロリー('はるさめ(芋・乾)',342). 食品のカロリー('あずき(乾)',339). 食品のカロリー('金山寺みそ',256). 食品のカロリー('おたふく豆',251). 食品のカロリー('豆きんとん',249). 食品のカロリー('つぶしあん',244). 食品のカロリー('うずら豆',237). 食品のカロリー('ゆば(生)',231). 食品のカロリー('がんもどき',228). 食品のカロリー('納豆',200). 食品のカロリー('納豆(ひきわり)',194). 食品のカロリー('だいず(ゆで)',180). 食品のカロリー('ひよこ豆(ゆで)',171). 食品のカロリー('こしあん',155). 食品のカロリー('厚揚げ/生揚げ',150). 食品のカロリー('えんどう豆(ゆで)',148). 食品のカロリー('いんげん豆(ゆで)',143). 食品のカロリー('紅花いんげん(ゆで)',121). 食品のカロリー('おから',89). 食品のカロリー('豆腐(焼き)',88). 食品のカロリー('豆腐(木綿)',72). 食品のカロリー('豆腐(絹ごし)',56). 食品のカロリー('豆乳',46). 食品のカロリー('マカダミアナッツ',720). 食品のカロリー('松の実',690). 食品のカロリー('くるみ',674). 食品のカロリー('ピスタチオ',615). 食品のカロリー('アーモンド',606). 食品のカロリー('ごま',599). 食品のカロリー('バターピーナッツ',592). 食品のカロリー('らっかせい',585). 食品のカロリー('カシューナッツ',576). 食品のカロリー('くり(甘露煮)',238). 食品のカロリー('くり(中国ぐり)',225). 食品のカロリー('くり(日本ぐり)',167). 食品のカロリー('ぎんなん',166). 食品のカロリー('干ししいたけ(乾)',182). 食品のカロリー('きくらげ(乾)',167). 食品のカロリー('エリンギ',24). 食品のカロリー('まつたけ',23). 食品のカロリー('えのきたけ',22). 食品のカロリー('しいたけ',18). 食品のカロリー('しめじ',18). 食品のカロリー('まいたけ',16). 食品のカロリー('マッシュルーム',16). 食品のカロリー('なめこ',14). 食品のカロリー('マッシュルーム(缶)',14). 食品のカロリー('なめこ(缶)',9). 食品のカロリー('あんこうのきも',445). 食品のカロリー('たたみいわし',372). 食品のカロリー('いわし(油漬)',359). 食品のカロリー('かつおぶし',356). 食品のカロリー('まぐろ(脂身)',344). 食品のカロリー('ふかひれ',342). 食品のカロリー('しめさば',339). 食品のカロリー('いわし(みりん干)',332). 食品のカロリー('煮干し',332). 食品のカロリー('さんま',310). 食品のカロリー('うなぎ(かば焼)',293). 食品のカロリー('たら(でんぶ)',278). 食品のカロリー('ツナ缶(油漬)',267). 食品のカロリー('たちうお',266). 食品のカロリー('さんま(開き)',261). 食品のカロリー('ぶり',257). 食品のカロリー('めざし',257). 食品のカロリー('はまち(生)',256). 食品のカロリー('身欠きにしん',246). 食品のカロリー('いわし(焼き)',244). 食品のカロリー('たい(焼)',226). 食品のカロリー('あじ(干物)',220). 食品のカロリー('ぎんだら',220). 食品のカロリー('いわし(生)',217). 食品のカロリー('にしん',216). 食品のカロリー('さば',202). 食品のカロリー('塩さけ',199). 食品のカロリー('あなご',194). 食品のカロリー('たい(生)',194). 食品のカロリー('いわし(丸干)',193). 食品のカロリー('さば(水煮缶)',190). 食品のカロリー('あゆ(焼)',177). 食品のカロリー('さわら',177). 食品のカロリー('ししゃも',177). 食品のカロリー('むつ',173). 食品のカロリー('あじ(焼)',164). 食品のカロリー('かれい(子持ち)',162). 食品のカロリー('スモークサーモン',161). 食品のカロリー('きんめだい',160). 食品のカロリー('さけ(生)',154). 食品のカロリー('かます(焼)',145). 食品のカロリー('ほっけ(開き)',142). 食品のカロリー('かじき',141). 食品のカロリー('いさき',127). 食品のカロリー('にじます',127). 食品のカロリー('いかなご',125). 食品のカロリー('まぐろ(赤身)',125). 食品のカロリー('ひらめ',124). 食品のカロリー('すずき',123). 食品のカロリー('あじ(生)',121). 食品のカロリー('うなぎ(きも)',118). 食品のカロリー('かれい(干し)',117). 食品のカロリー('ほっけ(生)',115). 食品のカロリー('かつお',114). 食品のカロリー('しらす干し',113). 食品のカロリー('はたはた',113). 食品のカロリー('めばる',109). 食品のカロリー('かれい',95). 食品のカロリー('さより',95). 食品のカロリー('きす',85). 食品のカロリー('ふぐ',85). 食品のカロリー('かわはぎ',80). 食品のカロリー('たら(生)',79). 食品のカロリー('しらうお',77). 食品のカロリー('わかさぎ',77). 食品のカロリー('ツナ缶(水煮)',71). 食品のカロリー('たら(塩)',65). 食品のカロリー('あんこう',58). 食品のカロリー('するめ',334). 食品のカロリー('わかさぎの佃煮',317). 食品のカロリー('すじこ',282). 食品のカロリー('いかなごの佃煮',282). 食品のカロリー('いくら',272). 食品のカロリー('えびの佃煮',244). 食品のカロリー('かつお節の佃煮',237). 食品のカロリー('干しえび',232). 食品のカロリー('あさりの佃煮',225). 食品のカロリー('はまぐりの佃煮',219). 食品のカロリー('粒うに',183). 食品のカロリー('たらこ',170). 食品のカロリー('魚肉ソーセージ',161). 食品のカロリー('さつま揚げ',139). 食品のカロリー('めんたいこ',126). 食品のカロリー('ちくわ',121). 食品のカロリー('うに',120). 食品のカロリー('いか(焼)',117). 食品のカロリー('いかの塩辛',117). 食品のカロリー('つみれ',113). 食品のカロリー('たいらがい',100). 食品のカロリー('しゃこ',98). 食品のカロリー('車えび',97). 食品のカロリー('ほたて(貝柱)',97). 食品のカロリー('大正えび',95). 食品のカロリー('かまぼこ',95). 食品のカロリー('はんぺん',94). 食品のカロリー('伊勢えび',92). 食品のカロリー('桜えび',91). 食品のカロリー('かにかまぼこ',90). 食品のカロリー('数の子',89). 食品のカロリー('さざえ',89). 食品のカロリー('いか(生)',88). 食品のカロリー('甘えび',87). 食品のカロリー('ばいがい',87). 食品のカロリー('つぶがい',86). 食品のカロリー('とりがい',86). 食品のカロリー('ほたるいか',84). 食品のカロリー('芝えび',83). 食品のカロリー('毛がに',83). 食品のカロリー('ブラックタイガー',82). 食品のカロリー('みる貝',82). 食品のカロリー('たらばがに',80). 食品のカロリー('なると',80). 食品のカロリー('たこ',76). 食品のカロリー('あわび',73). 食品のカロリー('かに缶',73). 食品のカロリー('ほっき貝',73). 食品のカロリー('ほたて(ひも付)',72). 食品のカロリー('ずわいがに',69). 食品のカロリー('あみの塩辛',65). 食品のカロリー('あおやぎ',61). 食品のカロリー('かき',60). 食品のカロリー('しじみ',51). 食品のカロリー('はまぐり',38). 食品のカロリー('あさり',30). 食品のカロリー('ほや',30). 食品のカロリー('くらげ',22). 食品のカロリー('牛ばら肉(和牛)',517). 食品のカロリー('フォアグラ',510). 食品のカロリー('牛サーロイン(和牛)',498). 食品のカロリー('サラミ',497). 食品のカロリー('牛リブロース(和牛)',468). 食品のカロリー('牛肩ロース(和牛)',411). 食品のカロリー('ベーコン',405). 食品のカロリー('たまご(卵黄)',387). 食品のカロリー('豚ばら肉',386). 食品のカロリー('レバーペースト',378). 食品のカロリー('牛ばら肉(輸入)',371). 食品のカロリー('牛ランプ(和牛)',347). 食品のカロリー('ウインナー',321). 食品のカロリー('ビーフジャーキー',315). 食品のカロリー('牛サーロイン(輸入)',298). 食品のカロリー('フランクフルト',298). 食品のカロリー('牛肉(小腸)',287). 食品のカロリー('牛肩肉(和牛)',286). 食品のカロリー('牛たん(舌)',269). 食品のカロリー('牛リブロース(輸入)',263). 食品のカロリー('豚ロース',263). 食品のカロリー('豚肩ロース',253). 食品のカロリー('生ハム',247). 食品のカロリー('牛もも肉(和牛)',246). 食品のカロリー('牛肩ロース(輸入)',240). 食品のカロリー('牛ランプ(輸入)',234). 食品のカロリー('豚足',230). 食品のカロリー('牛ひき肉',224). 食品のカロリー('マトン',224). 食品のカロリー('牛ひれ肉(和牛)',223). 食品のカロリー('豚ひき肉',221). 食品のカロリー('豚たん(舌)',221). 食品のカロリー('ピータン',214). 食品のカロリー('鶏手羽肉',211). 食品のカロリー('ベーコン(ロース)',211). 食品のカロリー('鶏はつ(心臓)',207). 食品のカロリー('コンビーフ缶',203). 食品のカロリー('鶏もも肉(皮付)',200). 食品のカロリー('ハム(ロース)',196). 食品のカロリー('ローストビーフ',196). 食品のカロリー('鶏むね肉(皮付)',191). 食品のカロリー('ショルダーベーコン',186). 食品のカロリー('豚もも肉',183). 食品のカロリー('牛もも肉(輸入)',182). 食品のカロリー('うずら卵(水煮缶)',182). 食品のカロリー('牛肩肉(輸入)',180). 食品のカロリー('うずら卵(生)',179). 食品のカロリー('焼豚',172). 食品のカロリー('鶏ひき肉',166). 食品のカロリー('ポーチドエッグ',164). 食品のカロリー('牛大腸',162). 食品のカロリー('たまご(生)',151). 食品のカロリー('たまご(ゆで)',151). 食品のカロリー('牛はつ(心臓)',142). 食品のカロリー('牛ひれ肉(輸入)',133). 食品のカロリー('牛レバー(肝臓)',132). 食品のカロリー('豚レバー(肝臓)',128). 食品のカロリー('かも',128). 食品のカロリー('子牛ばら肉',122). 食品のカロリー('ハム(ボンレス)',118). 食品のカロリー('鶏もも肉(皮なし)',116). 食品のカロリー('豚ひれ肉',115). 食品のカロリー('鶏レバー(肝臓)',111). 食品のカロリー('鶏むね肉(皮なし)',108). 食品のカロリー('鶏ささみ',105). 食品のカロリー('鶏砂ぎも',94). 食品のカロリー('たまご豆腐',79). 食品のカロリー('牛ミノ(胃)',62). 食品のカロリー('鶏軟骨',54). 食品のカロリー('たまご(卵白)',50). 食品のカロリー('焼きのり',188). 食品のカロリー('味付けのり',179). 食品のカロリー('あおのり(乾)',150). 食品のカロリー('ひじき(乾)',139). 食品のカロリー('こんぶ(乾)',138). 食品のカロリー('カットわかめ(乾)',138). 食品のカロリー('あおさ(乾)',130). 食品のカロリー('とろろこんぶ',117). 食品のカロリー('わかめ(素干し)',117). 食品のカロリー('塩昆布',110). 食品のカロリー('こんぶつくだ煮',84). 食品のカロリー('のりのつくだ煮',77). 食品のカロリー('めかぶわかめ',11). 食品のカロリー('塩蔵わかめ(塩抜)',11). 食品のカロリー('もずく',4). 食品のカロリー('かんてん',3). 食品のカロリー('ところてん',2). 食品のカロリー('コーヒーミルク(粉/植物性)',568). 食品のカロリー('コーヒーミルク(粉/乳脂肪)',518). 食品のカロリー('パルメザンチーズ',475). 食品のカロリー('生クリーム(乳脂肪)',433). 食品のカロリー('ホイップクリーム(乳脂肪)',422). 食品のカロリー('ホイップクリーム(植物性)',402). 食品のカロリー('生クリーム(植物性)',392). 食品のカロリー('脱脂粉乳(粉)',359). 食品のカロリー('チーズ(クリーム)',346). 食品のカロリー('プロセスチーズ',339). 食品のカロリー('加糖練乳',331). 食品のカロリー('カマンベールチーズ',310). 食品のカロリー('コーヒーミルク(液/植物性)',248). 食品のカロリー('アイスクリーム(ラクトアイス・普通脂肪)',224). 食品のカロリー('乳酸菌飲料(殺菌乳製品)',217). 食品のカロリー('アイスクリーム(高脂肪)',212). 食品のカロリー('コーヒーミルク(液/乳脂肪)',211). 食品のカロリー('アイスクリーム(普通脂肪)',180). 食品のカロリー('アイスクリーム(アイスミルク)',167). 食品のカロリー('アイスクリーム(ソフトクリーム)',146). 食品のカロリー('シャーベット',127). 食品のカロリー('アイスクリーム(ラクトアイス・低脂肪)',108). 食品のカロリー('カッテージチーズ',105). 食品のカロリー('牛乳(特濃)',73). 食品のカロリー('乳酸菌飲料(乳製品)',71). 食品のカロリー('牛乳(普通)',67). 食品のカロリー('ヨーグルト(脱脂/加糖)',67). 食品のカロリー('ヨーグルト(飲料)',65). 食品のカロリー('ヨーグルト(全脂/無糖)',62). 食品のカロリー('コーヒー牛乳',56). 食品のカロリー('牛乳(低脂肪乳)',46). 食品のカロリー('フルーツ牛乳',46). 食品のカロリー('牛乳(脱脂乳)',33). 料理中の遺失カロリー比率(カレー,5) :- !. 料理中の遺失カロリー比率(_料理名,10) :- sub_atom(_料理名,_,3,_,スープ),!. 料理中の遺失カロリー比率(_,0). レシピ(カエルのバターとブドウ酒の煮込み,皮を剥いだカエルの足,6,900 g). レシピ(カエルのバターとブドウ酒の煮込み,辛口の白ブドウ酒,6,200 cc). レシピ(カエルのバターとブドウ酒の煮込み,小麦粉,6,3 g). レシピ(カエルのバターとブドウ酒の煮込み,塩,6,少々). レシピ(カエルのバターとブドウ酒の煮込み,パセリのみじん切り,6,2-3 枚). レシピ(カエルのバターとブドウ酒の煮込み,レモン,6,1 個). レシピ(すずきの白ブドウ酒入り蒸し焼き,'海すずき(1.1kg)',6,1 尾). レシピ(すずきの白ブドウ酒入り蒸し焼き,塩,6,少量). レシピ(すずきの白ブドウ酒入り蒸し焼き,辛口白ブドウ酒,6,400 cc). レシピ(すずきの白ブドウ酒入り蒸し焼き,バター,6,25 g). 作り方(カエルのバターとブドウ酒の煮込み,1,'マリネのためにブドウ酒を使ってカエルの足を浸す'). 作り方(カエルのバターとブドウ酒の煮込み,2,'バターを深底のフライパンに溶かす'). 作り方(カエルのバターとブドウ酒の煮込み,3,'マリネからカエルの足を取り出したおく'). 作り方(カエルのバターとブドウ酒の煮込み,4,'フライパンにブドウ酒をそそぎ、バターとよく混ぜ合わせ、足を加える'). 作り方(カエルのバターとブドウ酒の煮込み,5,'ブドウ酒が半量煮つまるまで、中火で煮る'). 作り方(カエルのバターとブドウ酒の煮込み,6,'小麦粉、塩少々、パセリ、水 30ccを混ぜ合わせる'). 作り方(カエルのバターとブドウ酒の煮込み,7,'フライパンに入れて混ぜ合わせる'). 作り方(カエルのバターとブドウ酒の煮込み,8,'中火でさらに15分火を通し続ける'). 作り方(カエルのバターとブドウ酒の煮込み,9,'供する前に、カエルの足にレモン汁をふりかけて、供する'). 作り方(すずきの白ブドウ酒入り蒸し焼き,1,'皮に傷をつけないように下ごしらえする。魚はきざみ目をつけて内側に塩をする。'). 作り方(すずきの白ブドウ酒入り蒸し焼き,2,'鍋にブドウ酒、バター、塩少量を入れて魚を入れ、蓋をして中火のオープンで約20分間魚がやわらかくなるまで蒸し焼きにする。'). 作り方(すずきの白ブドウ酒入り蒸し焼き,3,'魚を皿に盛り魚の背中に2~3つの切り目をつけ、上から濾した煮汁をかけてすぐ供する。'). 材料の姿(生姜,N,個,_数量のグラム単位) :- _数量のグラム単位 is N * 30. 材料の姿('たまねぎ(中)',N,個,_数量のグラム単位) :- _数量のグラム単位 is N * 250. 材料の姿(_,A,_,A,_). 料理のデータベースを作成し、複数のデータの中からカロリーが最大と最小の料理の全データを出力するプログラムを作成せよ :- findsetof(_料理名,レシピ(_料理名,_,_),_料理名ならび), append(_,[_料理名|_],_料理名ならび), findall([_カロリー,_料理名], 料理のカロリー(_料理名,_カロリー), _カロリー・料理名ならび), max(_カロリー・料理名ならび,[_カロリーが最大の料理のカロリー,_カロリーが最大の料理名]), min(_カロリー・料理名ならび,[_カロリーが最小の料理のカロリー,_カロリーが最小の料理名]), 料理の全データを出力する(_カロリーが最大の料理名,_カロリーが最大の料理のカロリー), 料理の全データを出力する(_カロリーが最小の料理名,_カロリーが最小の料理のカロリー),!. 料理のカロリー(_料理名,_カロリー) :- findsum(_カロリー,( レシピ(_料理名,_材料,_数量,_), 材料の姿(_材料,_数量,_,_数量グラム単位), 食品のカロリー(_材料,_100gあたりのカロリー), _カロリー is _100gあたりのカロリー * _数量グラム単位 / 100), _カロリー合計), 料理中の遺失カロリー比率(_料理名,_遺失カロリー比率), _カロリー is _カロリー合計 * (100-_遺失カロリー比率) / 100. 料理の全データを出力する(_料理名,_カロリー) :- findall([_材料,_数量グラム単位],レシピ(材料,_料理名,_材料,_数量,_),_材料ならび), findall(_作り方,作り方(_料理名,_,_作り方),_作り方ならび), write_formatted('料理名 %t\nカロリー量 %t\n',[_料理名,カロリー]), 材料の表示(_材料・数量ならび), 作り方の表示(_作り方ならび),!. 材料の表示(_材料・数量ならび) :- write('材料,数量\n'), append(_,[[_材料,_数量グラム単位]|R],_材料・数量ならび), write_formatted('%t,%t\n',_材料,_数量グラム単位]), R = [],!. 作り方の表示(_作り方ならび) :- write('\n作り方\n\n'), append(L0,[_作り方|R],_作り方ならび), length([_|L0],_手順番号), write_formatted('%t ... %t\n',[_手順番号,_作り方]), R = [],!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/730 # # ・DBMS名とバージョン #  MySQL 5.1 # ・テーブルデータ #  記録ID(通し番号)、ユーザID、日時、金額、購入品目ID # ・欲しい結果 #  購入品目ID、日時(最新の1件)、金額(〃)  //ただしユーザID=A # # ・説明 #  ユーザID=Aの、購入品目IDごとに、最新の日時と金額を表示させたいです。 #  (購入品目IDが1〜10まであったら、10行の結果が返ってくるような) #  どこに副問合せを使っていいか分からず詰まりました。どなたかお願いします。 # # 'ユーザID=Aの、購入品目IDごとに、最新の日時と金額を表示させたいです。' :- 'ユーザIDを指定して、購入品目IDごとに、最新の日時と金額を表示'('A'). 'ユーザIDを指定して、購入品目IDごとに、最新の日時と金額を表示'(_ユーザID) :- findsetof(_購入品目ID, テーブルデータ(_記録ID,_ユーザID,_日時,_金額,_購入品目ID), L1), append(_,[_購入品目ID|R],L1), findmax([_日時,_その日の合計金額], findsum(_金額,( テーブルデータ(_記録ID,_ユーザID,_日時,_金額,_購入品目ID)), _その日の合計金額), [_日時,_その日の合計金額]), write_formatted('%t,%t,%t\n',[_ユーザID,_日時,_その日の金額]), R = []. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/642 # # +---+------+----+ # | id|parent|name| # +---+------+----+ # | 1 | NULL |taro| # | 2 |  1 |jiro| # | 3 |  1 |sabu| # | 4 |  2 |siro| # | 5 | 3 |hana| # +---+------+----+ # # 上記のようなユーザーID(id)とその親情報(parent)のテーブルで、 # 指定したIDの子と孫の一覧を取得するにはどうすればいいですか? # 1の場合、jiro、sabu、siroを取得したいです。 # 子と孫の総数だけでもかまいません。 # # 親子(1,[],taro). 親子(2,1,jiro). 親子(3,1,sabu). 親子(4,2,siro). 親子(5,3,hana). 指定したIDの子と孫の取得(_指定したid,_子と孫ならび) :- findsetof(_id,親子(_id,_,_),L), append(_,[_指定したid|_],L), 孫ならびの取得(_指定したid,_孫ならび), 子ならびの取得(_指定したid,_子ならび), append(_子ならび,_孫ならび,_子と孫ならび). 孫ならびの取得(_id2,_孫ならび) :- findall(_name,( 親子(_id1,_id2,_), 親子(_id,_id1,_name)), _孫ならび),!. 子ならびの取得(_id2,_子ならび) :- findall(_name,親子(_id,_id2,_name),_子ならび),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1289913298/83 # # ポーカーゲームを作るプログラムの課題を教えてください。 # [1] プログラムまとめ # [2] 課題1のストレート、フラッシュ、フルハウスをヒントを使って判定する関数を作る。 # # /* ヒント: この関数を使うと、 判定が簡単かも */ # void distrib(struct card h[], int dist[]){ # int i; # for(i = 0; i < 14; i++){ # dist[i] = 0;} # for(i = 0; i < 5; i++){ # dist[h[i].pips]++;}} # # int is_straight(struct card h[]){ # /* 課題1 */ # return 0;} # # int is_flush(struct card h[]){ # /* 課題1 */} # # int is_fullhouse(struct card h[]){ # /* 課題1 */ # return 0;} # # card h[] は手札のカード # h[].pips は手札のカードの番号 # h[].suit は手札のカードのマークのことです ポーカーの役(_手札ならび,フラッシュ) :- all(_手札ならび,[_,_共通マーク]), \+(ポーカーの役(_手札ならび,ストレート)),!. ポーカーの役(_手札ならび,ストレート) :- sort(_手札ならび,L), L = [Min|R], Max is Min + 4, findall(N,for(Min,N,Max),L), \+all(_手札ならび,[_,_共通マーク])),!. ポーカーの役(_手札ならび,フルハウス) :- findsetof(_番号,append(_,[[_番号,_]|_],_手札ならび),[_番号1,_番号2]), count(append(_,[[_番号1,_]|_],_手札ならび),Count1), Count1 >= 2, count(append(_,[[_番号2,_]|_],_手札ならび),Count2), Count2 >= 2,!. ポーカーの役(_手札ならび,フルハウス) :- sort(_手札ならび,L), フルハウス(L). フルハウス([[_A,_],[_A,_],[_B,_],[_B,_],[_B,_]]) :- \+(A = B),!. フルハウス([[_A,_],[_A,_],[_A,_],[_B,_],[_B,_]]) :- \+(A = B),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/627 # # mysql 5.0 (windows 7)です # 下記のようなテーブルで # amountの合計の最も多いidを取得するsql文がわかりません… # # select id, sum(amount) as "total" from orders # group by id order by total desc limit 1; # # とすれば一応取得できたのですが、別の方法はないでしょうか # 初歩的な質問ですみません… # # +------+------+--------+ # | id | name | amount | # +------+------+--------+ # | 1 | C1 | 3 | # | 1 | C2 | 10 | # | 2 | C2 | 5 | # | 2 | C3 | 10 | # | 3 | C3 | 2 | # +------+------+--------+ # 'amountの合計の最も多いidを取得する'(_最もaumout合計が多いid) :- find_sum_max([_id,_値],orders(_id,_,_値),[_最もamount合計が多いid,_最大合計値]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % _合計値 は任意の変数として、利用者が設定する find_sum_max([_鍵,_値],P,_合計値,_合計値の条件,[_鍵,_最大合計値]) :- findall([_鍵,_値],( 単一(_鍵,P)), findsum(_値,P,_合計値)), L), findmax(_合計値,( append(_,[[_鍵,_合計値]|_],L), _合計値の条件), _最大合計値), append(_,[[_鍵,_最大合計値]|_],L). find_sum_min([_鍵,_値],P,_合計値,_合計値の条件,[_鍵,_最小合計値]) :- findall([_鍵,_値],( 単一(_鍵,P)), findsum(_値,P,_合計値)), L), findmin(_合計値,( append(_,[[_鍵,_合計値]|_],L), _合計値の条件), _最小合計値), append(_,[[_鍵,_最小合計値]|_],L). find_sum_max([_鍵,_値],P,[_鍵,_最大合計値]) :- findall([_鍵,_値],( 単一(_鍵,P)), findsum(_値,P,_合計値)), L), findmax(_合計値,append(_,[[_鍵,_合計値]|_],L),_最大合計値), append(_,[[_鍵,_最大合計値]|_],L). find_sum_min([_鍵,_値],P,[_鍵,_最小合計値]) :- findall([_鍵,_値],( 単一(_鍵,P)), findsum(_値,P,_合計値)), L), findmin(_合計値,append(_,[[_鍵,_合計値]|_],L),_最小合計値), append(_,[[_鍵,_最小合計値]|_],L). 単一(A,P) :- findsetof(A,P,L),!, append(_,[A|_],L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/607 # # MySQLServer5.1(WinXP)です。 # # 下記のような3種類のテーブルがあります。 # これを集計して、指定したユーザーの指定月のアクセス日時と売上げ金額を表にしたいと思っています。 # # こんな感じに。 # # +--+--------+----------+-------+-----+ # | id | username| date   | access | sales | # +--+--------+----------+-------+-----+ # | 1 | admin | 2010-11-13 |   2 | 5000 | # | 1 | admin | 2010-11-14 |   2 | 5000 | # | 1 | admin | 2010-11-15 |  1 | 20000 | # +--+--------+----------+-------+-----+ # # # SELECT u.id AS id, u.username, DATE(a.created_at) AS date, COUNT(*) AS access, SUM(s.amount) AS sales # FROM sf_guard_user u INNER JOIN sales s ON u.username = s.user_id LEFT JOIN access_log a ON u.username = a.user_id # WHERE (u.username = 'admin' AND a.created_at > '2010-11-01 00:00:00' AND a.created_at < '2010-11-30 23:59:59') GROUP BY date ORDER BY a.created_at; # とやってみたのですがダメでした;; # # # ■ユーザー情報テーブル # mysql> select id,username from user; # +--+---------+ # | id | username | # +--+---------+ # | 1 | admin   | # +--+---------+ # # ■アクセスログテーブル # mysql> select * from access_log; # +--+-------+--------+------------------+ # | id | user_id | ip     | created_at      | # +--+-------+--------+------------------+ # | 1 | admin  | 127.0.0.1 | 2010-11-13 21:56:54 | # | 2 | admin  | 127.0.0.1 | 2010-11-13 21:56:54 | # | 3 | admin  | 127.0.0.1 | 2010-11-14 21:56:54 | # | 4 | admin  | 127.0.0.1 | 2010-11-14 21:56:54 | # | 5 | admin  | 127.0.0.1 | 2010-11-15 21:56:54 | # +--+-------+--------+------------------+ # # ■売上げ金額テーブル # mysql> select * from sales; # +--+-------+------+------------------+ # | id | user_id | amount| created_at      | # +--+-------+------+------------------+ # | 1 | admin  |  5000 | 2010-11-13 21:56:54 | # | 2 | admin  |  5000 | 2010-11-14 21:56:54 | # | 3 | admin  |  5000 | 2010-11-15 21:56:54 | # | 4 | admin  |  5000 | 2010-11-15 21:56:54 | # +--+-------+------+------------------+ # # '下記のような3種類のテーブルがあります。これを集計して、指定したユーザーの指定月のアクセス日時と売上げ金額を表にしたいと思っています。'(_username) :- user(_id,_username), アクセスログテーブル_date(_username,_アクセスログ_dateならび), 売上げ金額テーブル_date(_username,_売上金額テーブル_dateならび), 共通部分(_アクセスログ_dateならび,_売上金額テーブル_dateならび,_date_共通部分), write('+--+-------+--------+------------------+ \n'), write('| id | user_id | amount| created_at      | \n'), write('+--+-------+------+------------------+ \n), append(L0,[_date|R],_date_共通部分), length(L0,Len0), _id is Len0 + 1, count(( access_log(_,_user_id,_ip,_create_at), sub_atom(_create_at,0,10,_,_create_at)), _access), findsum(_amount,( sales(_,_user_id,_amount,_create_at), sub_atom(_create_at,0,10,_,_create_at)), _sales), write_formatted('| %t | %t | %t | %t | %t |\n',[_id,_username,_date,_access,_sales]), R = [], write('+--+-------+------+------------------+\n'). アクセスログテーブル_date(_user_id,_dateならび) :- findsetof(_date,( access_log(_,_user_id,_,_created_at), sub_atom(_create_at,0,10,_,_date)), _dateならび). 売上げ金額テーブル_date(_user_id,_dateならび) :- findsetof(_date,( sales(_,_user_id,_amount,_created_at), sub_atom(_create_at,0,10,_,_date)), _dateならび). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/587 # # 下のようなカラムがあるのですが、value1〜3に1回でも出てくる値を # 重複なく取得したいのですが、うまくSQLで書けるものでしょうか。 # key, value1, valu2, value3(value1〜3は任意の文字列) # # たとえば、3個のレコード # 1, AAA, BBB, CCC # 2, DDD, AAA, CCC # 3, EEE, FFF, AAA # があった場合、AAA, BBB, CCC, DDD, EEE, FFFを出力したいです。 # # % table(_key,_value1,_value2,_value3). table(1,'AAA','BBB','CCC'). table(2,'DDD','AAA','CCC'). table(3,'EEE','FFF','AAA'). 'tableのvalue1〜3に1回でも出てくる値を重複なく取得したい' :- 'tableのvalue1〜3に1回でも出てくる値を重複なく取得したい'(L), append(_,[X|R],L), write_formatted('%t\n',[X]), R = []. 'tableのvalue1〜3に1回でも出てくる値を重複なく取得したい'(L) :- findsetof(_value,( table(_,_value1,_value2,_value3), append(_,[_value|_],[_value1,_value2,_value3])), L). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1288531658/172 # # [1] 授業単元: アルゴリズムとデータ構造 # [2] 問題文(含コード&リンク): #  typedef struct{char name[256]; unsigned char sex; unsigned char age;} PERSONAL_DATA # 上記の構造体PERSONAL_DATA型の配列(要素数n)に格納された # n人の名前・性別・年齢のデータの中から同じ年齢の2人組の名前を全て表示せよ。 # % n人が反映されていない。 'n人の名前・性別・年齢のデータの中から同じ年齢の2人組の名前を全て表示せよ' :- findsetof(_年齢,個人データ(_名前,_性別,_年齢),_年齢ならび), append(_,[_年齢|R],_年齢ならび), findall(_氏名,個人データ(_名前,_性別,_年齢),_氏名ならび), 同じ年齢の2人組の名前を表示(_年齢,_氏名ならび), R = []. 同じ年齢の2人組の名前を表示(_,[]) :- !. 同じ年齢の2人組の名前を表示(_,[_]) :- !. 同じ年齢の2人組の名前を表示(_年齢,_氏名ならび) :- write_formatted('年齢=%t',[_年齢]), 組み合わせ(_氏名ならび,2,L), write_formatted(' (%t,%t)',L), fail. 同じ年齢の2人組の名前を表示(_,_) :- write('\n'). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/531 # # ACCESS SQLで以下のような処理はできるでしょうか? # (VBAの機能等を含めないSQLの処理結果のみで) # # 【テーブル】 # Tくだもの(名前, 名前) # Tアンケート(名前, 評価) ←評価には1〜5の数値が入る # # 【結果】 # みかん, 1, 3, 5, 3, 4, ... (以降アンケートの数だけ続く) # 評価値の列表示 :- findsetof(_名前,くだもの(_名前),_名前ならび), append(_,[_名前|R],_名前ならび), findall(_評価,アンケート(_名前,_評価),_評価ならび), concat_atom(_評価ならび,', ',_評価表示文字列), write_formatted('%t, %t\n',[_名前,_評価表示文字列]), R = []. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 評価値の列表示 :- くだもの(_名前), findall(_評価,アンケート(_名前,_評価),_評価ならび), concat_atom(_評価ならび,', ',_評価表示文字列), write_formatted('%t, %t\n',[_名前,_評価表示文字列]), fail. 評価値の列表示. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1272006124 # # <問題> # 全社員が売上を記録した日を求めよ。 これをPrologプログラムとして表現しなさい。 全社員が売上を記録した日を求めよ(_日) :- count(社員(_社員),_社員人数), findsetof(_日,売上(_社員,_日,_データ),L1), append(_,[_日|R],L1), findsetof(_社員,社員(_社員,_日,_データ),L2), length(L2,_社員人数). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% count(P,N) :- findsum(1,P,F), N is truncate(F). findsum(_選択項,_項,_合計値) :- findall(_選択項,_項,_値ならび), 加算(_値ならび,_合計値),!. findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). 加算(trunc(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A is trunc(B)),SL),!. 加算(四捨五入(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 四捨五入(B)),SL),!. 加算(切捨て(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切捨て(B)),SL),!. 加算(切り上げ(L),SL) :- 加算(L,SL2), findall(A,(member(B,SL2) , A は 切り上げ(B)),SL),!. 加算([],L) :- var(L), L = 0.0e+00,!. 加算([],L) :- \+(var(L)), 加算の変数に零をおく(L),!. 加算([L|R],SL) :- ならび(L), 転置([L|R],L1), 加算_2(L1,SL),!. 加算(X,S) :- 加算_1(X,0.0e+00,S). 加算_1([],S,S) :- !. 加算_1([A|R],Y,S) :- ならび(A), ならび(Y), !, ならび加算(A,Y,Z), 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,I), integer(I), Z is I + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), atom_number(A,F), real(F), Z is F + Y, 加算_1(R,Z,S),!. 加算_1([A|R],Y,S) :- atom(A), 加算_1(R,Y,S),!. 加算_1([A|R],Y,S) :- A1 は A, Z is A1 + Y, 加算_1(R,Z,S). 加算_2([],[]) :- !. 加算_2([L|R],[S|R2]) :- 加算(L,S), 加算_2(R,R2). ならび加算([],L,L) :- !. ならび加算(L,[],L) :- !. ならび加算([A|R],[B|R1],[C|R2]) :- C is A + B, ならび加算(R,R1,R2). 加算の変数に零をおく([]) :- !. 加算の変数に零をおく([A|R]) :- 変数(A), A = 0.0e+00, 加算の変数に零をおく(R),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/tech/1272006124 # # <問題> # 全社員が売上を記録した日を求めよ。 # これを Prolog プログラムとして表現しなさい。 売上(稲葉,'20140228'). 売上(尾崎,'20140227'). 売上(稲葉,'20140226'). 売上(尾崎,'20140226'). 売上(尾崎,'20140226'). 売上(尾崎,'20140228'). 社員(尾崎). 社員(稲葉). '全社員が売上を記録した日を求めよ。'(_全社員が売上を記録した日) :- findsetof(_日,売上(_,_日),L), member(_全社員が売上を記録した日,L), forall(社員(_社員),売上(_社員,_全社員が売上を記録した日)). findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L) . % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1056938879/131 # # table1 # id 名前 状態_id # ------------------ # 1 キムラ A # 2 田中   B # # # talbe2 # id 状態_id 状態(varchar) # ------------------ # 1 A 0 # 2 A 0 # 3 A 1 # 4 B 0 # 5 B 0 # # 結果 # 名前 状態 # ------------------ # キムラ 1 # 田中 0 # # になるようなSQL文でどう書きまっか?ちなみにORACLE9i。 # 結果(_名前,_状態) :- findsetof(_名前,table1(_,_名前,_),L1), sort(L1,L2), append(_,[_名前|_],L2), table1(_id,_名前,_状態_id) table2(_id,_状態_id,_状態). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/500 # # No-色 # レコード1 001,赤 # レコード2 002,赤 # レコード3 003,青 # レコード4 004,青 # レコード5, 005,赤 # レコード6, 006,黒 # # このデータで、 『select 色,count(色 from テーブル group by 色 』とした時 # 最大レコード数(この場合、赤の5)を取得したいのですが・・・ # 定義された節数のもっとも多い色は(_色,_度数) :- findsetof(_色,テーブル(_No,_色),L1), findall([_度数,_色],( member(_色,L1), count(テーブル(_,_色),度数)), L2), findmax(_度数,member([_度数,_],L2),_最大度数), append(_,[[_度数,_色]|R],L2). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/408 # # よろしくお願いいたします。 # # ・DBMS名とバージョン #   HiRDB Ver8 # # ・テーブルデータ # <Aテーブル> # A1   A2   A3   A4   A5 # ------- ------- ------- ------- ---------- # XXXXXXX XX1   ABC 3 2009/05/08 # WWCWWCW WW2   CCB 1 2008/03/21 # DDDDDDD DD1   JPN 5 2007/08/08 # GGGGGGG GX9   SOX 2 1977/01/04 # FFFFFFF USJ   NPB 3 2001/09/11 # # # <Bテーブル> # B1   B2   B3   B4   B5 # ------- ------- ------- ------- ---------- # XXXXXXX XX1  ibicha  oshimu 2002/07/05 # XXXXXXX XX1  takeshi okada 2005/07/15 # XXXXXXX XX1  kamo shu 1857/09/25 # WWCWWCW WW2  wao wao 2008/10/22 # DDDDDDD DD1  ui hhh 2006/06/30 # DDDDDDD DD1  jojoj x5xx 1999/09/09 # DDDDDDD DD1  momo hara 2005/03/07 # DDDDDDD DD1  itai u- 2003/12/22 # DDDDDDD DD1  koma nogoal 2007/04/26 # GGGGGGG GX9   dame record 2009/11/14 # FFFFFFF USJ   iki tai 1995/08/15 # FFFFFFF USJ  sst ebuspi 2004/01/05 # FFFFFFF USJ  bb pp 2009/08/23 # # ・欲しい結果 # A1   A2   B1   B2   A4 B1andB2COUNT # ------- ------ ------- ------- ------- ------------ # GGGGGGG GX9 GGGGGGG GX9 2 1 # # # ・説明 # SQLで違うテーブルの値を比較して値に差があるレコードを抽出したいのですがヒントをいただけないでしょうか。 # A1とB1は、A2とB2は同じデータが基本です。 # Aテーブルの「A4」カラムにはBテーブルのレコード数を持っています。 # しかし、よくよく見るとAテーブルの「GGGGGGG」のA4には「2」のはずなのにBテーブルには実際にレコードは1つしかありません。 # こういう状態になってしまっているのを割り出したいのですがどのようにA4とBテーブルで数があってないものを抽出できるでしょうか。 # よろしくお願いいたします。 # # 集約値A4とBテーブルの組数が不整合であるか、Bテーブルに存在する組の集約がAテーブルにない :- findsetof([A1,A2],'Aテーブル'(A1,A2,_,_,_),L1), write('集約値A4とBテーブル組の不整合'), 集約値A4とBテーブル組の不整合(L1), findsetof([B1,B2],(Bテーブル'(B1,B2,_,_,_),L2), write('Bテーブルは存在するがAテーブルに集約されていない\n'), 'Bテーブルは存在するがAテーブルに集約されていない'(L2),!. 集約値A4とBテーブル組の不整合([]) :- !. 集約値A4とBテーブル組の不整合([[A1,A2]|R]) :- 'Aテーブル'(A1,A2,_,A4,_), count('Bテーブル'(A1,A2,_,_,_),Count), 診断(A1,A2,A4,Count), 集約値A4とBテーブル組の不整合(R). 診断(A1,A2,A4,0) :- write('対応するBテーブルの組がありません\n'),!. 診断(A1,A2,A4,Count) :- \+(A4=Count), write_formatted('Aテーブルのキー%t,%tの集約値A4=%tとBテーブルの同一キーのカウントが不整合です\n',[A1,A2,A4,Count]),!. 診断(_,_,_,_). 'Bテーブルは存在するがAテーブルに集約されていない'([]) :- !. 'Bテーブルは存在するがAテーブルに集約されていない'([[B1,B2]|R]) :- 'Aテーブル'(B1,B2,_,_,_), 'Bテーブルは存在するがAテーブルに集約されていない'(R),!. 'Bテーブルは存在するがAテーブルに集約されていない'([[B1,B2]|R]) :- 'Bテーブル'(B1,B2,B3,B4,B5), write_fromatted('Aテーブルに集約が存在しない組は%t,%tです\n',[B1,B2,B3,B4,B5]), 'Bテーブルは存在するがAテーブルに集約されていない'(R),!. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/451 # # 最近になってDBの勉強を始めたのですが詰ってしまったのでちょっと質問させてください。 # # 使っているのは、derbyです、バージョンはij起動時に10.5と表示されています # # ・テーブルデータ # 受注表 # ------------------- # 顧客コード | 受注個数 # ------------------- # 001 | 100 # 002 | 200 # 003 | 100 # 001 | 300 # 003 | 400 # # ・欲しい結果 # 結果 # --------------------------------- # 顧客コード | 個人平均値 | 全体平均値 # --------------------------------- # 001 |200 |240 # 002 |200 |240 # 003 |250 |240 # # ・説明 # SELECT #   顧客コード, #   AVG(受注個数) AS 個人平均値, #   (SELECT AVG(受注個数) FROM 受注表) AS 全体平均値  # FROM # 受注表 # GROUP BY # 顧客コード; # # 上記のSQLだとエラーが出て動かない(エラーメッセージ失念してしまいました) # どこがどう悪いのか現在の自分では分からなくてどうしようもない状態です。 # '受注簿から 顧客コード | 個人平均値 | 全体平均値 を各行に表示' :- findavg(_受注個数,受注表(_,_受注個数),_全体平均値), findsetof(_顧客コード,受注表(_顧客コード,_受注個数),L), append(_,[_顧客コード|R],L), findavg(_受注個数,受注表(_顧客コード,_受注個数),_個人平均値), write_formatted('%t | %t | %t\n',[_顧客コード,_個人平均値,_全体平均値]), R = []. % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/609 # # postgres8.4を使ってます。 # レコード数が3件以上あるものを取得したいのですが # どう書けばよいでしょうか。 # # やりたいことのイメージはこんな感じです。 # select recordCD from Table where recordCD in (select recordCD from Table where count(recordCD) > 3); # % これだとrecodCDが件数分出力されてしまうので、一件のみの出力に変更した recordCDの位置を得る(_引数の数,_位置番号) :- 'テーブル構造'('Table',_引数の数,_位置番号,recordCD). レコード数が3件以上あるものを取得する(_recordCD) :- recordCDの位置を得る(_引数の数,_位置番号), functor(Q,'Table',_引数の数), arg(_位置番号,Q,_recordCD), findsetof(_recordCD,call(Q),L1), member(_recordCD,L1), count(Q,Count), Count >= 3. % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/609 # # postgres8.4を使ってます。 # レコード数が3件以上あるものを取得したいのですが # どう書けばよいでしょうか。 # # やりたいことのイメージはこんな感じです。 # select recordCD from Table where recordCD in (select recordCD from Table where count(recordCD) > 3); # % これだとrecodCDが件数分出力されてしまうので、一件のみの出力に変更した recordCDの位置を得る(_引数の数,_位置番号) :- 'テーブル構造'('Table',_引数の数,_位置番号,recordCD). レコード数が3件以上あるものを取得する(_recordCD) :- recordCDの位置を得る(_引数の数,_位置番号), functor(Q,'Table',_引数の数), arg(_位置番号,Q,_recordCD), findsetof(_recordCD,call(Q),L1), member(_recordCD,L1), count(Q,Count), Count >= 3. % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/594 # #(問) # 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 # # このようなテーブルから、各idに対して最新の5件だけ抽出しなさい 各idに対して最新の5件だけ抽出する(_ID,_DATE,_DATA) :- findsetof(_ID,テーブル(_ID_1,_DATE_1,_DATA_1),L1), member(_ID,L1), findall([_DATE,_ID,_DATE,_DATA],テーブル(_ID1,_DATE,_DATA),L2), 最新の5件を抽出(L3,Len,_ID,_DATE,_DATA). 最新の5件を抽出(L1,_ID,_DATE,_DATA) :- sort(L1,L2), reverse(L2,L3), length(L3,Len), '5件を抽出'(L3,Len,_ID,_DATE,_DATA). '5件を抽出'(L,Len,_ID,_DATE,_DATA) :- Len =< 5, member([_,_ID,_DATE,_DATA],L). '5件を抽出'(L,Len,_ID,_DATE,_DATA) :- Len > 5, for(1,N,5), list_nth(N,L,[_,_ID,_DATE,_DATA]), N =< 5. % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/445 # # MySQL 5.1での質問です。 # # A B C # 1 q name1 # 2 w name2 # 3 e name3 # 4 q name4 # 5 t name5 # # 上記テーブルのB列の重複を除いたA,B,C列がほしい場合 # # SELECT DISTINCT B FROM table_name; # # ではB列の重複を除くだけで他の列がとれません。他の列も併せて取得する場合はどのような解決策がありますか? # # 望んでる結果は以下のものです。 # # A B C # 1 q name1 # 2 w name2 # 3 e name3 # 5 t name5 # 'B列の重複を除く際のルール'(_重複行ならび,_重複を除いた行) :- _重複行ならび = [_重複を除いた行|_],!. 'B列の重複を除いたA,B,C列がほしい'(_重複を除いた行) :- findsetof(_B列,foo(_,_B列,_),_重複を取り除いたB列ならび), member(_B列,_重複を取り除いたB列ならび), findall(_行,( member([_A列,_B列,_C列],foo(_A列,_B列,_C列)), L1), 'B列の重複を除く際のルール'(L1,_重複を除いた行). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/386 # # ・DBMS名とバージョン #   SQL Server Compact 3.5 # # ・テーブルデータ 家計簿のようなデータです # Cd1 Cd2  Item      Cost # ---+----+-----------+---------------- # 1   0    食費      NULL # 1   1    弁当      500 # 2   0    光熱費     NULL # 2   1    水道料     1000 # 2   1    水道料     2000 # 2   2    ガス料     4000   # # ・欲しい結果 # Cd1 Cd2  Item      Sum # ---+----+-----------+---------------- # 1   0    食費      500 # 2   0    光熱費    7000 # # ・説明 # Cd1が大分類、Cd2が中分類を表してます。 # Cd2が0の場合、Itemは大分類の名称。それ以外の場合、中分類の名称が入ってます。 # 大分類ごとにItemと合計額が欲しいです。 # # # 大分類ごとにItemと合計額が欲しい :- findsetof([_Cd1,_Item],家計簿(_cd1,0,_Item,_),L1), member([_Cd1,_Item],L1), findsum(_Cost,(家計簿(_Cd1,_Cd2,_,_Cost),\+(_Cd2=0)),_Sum), write_formatted('%t %t %t %t\n',[_Cd1,0,_Item,_Sum]), fail. 大分類ごとにItemと合計額が欲しい. % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/374 # # はじめまして # # ・Access2000 # # 下のようなテーブルがあったときに # # テーブルA # 名前 科目 点数 # ---------------------- # 岡村 国語 51 # 岡村 数学 48 # 岡村 英語 39 # 徳田 国語 60 # 徳田 数学 30 # 徳田 英語 48 # 渡辺 国語 28 # 渡辺 数学 67 # 渡辺 英語 25 # # 下のように各科目の最高点を名前つきで取得するにはどうすればいいのでしょうか? # # 結果(各科目の最高点) # ---------------------- # 徳田 国語 60 # 岡村 数学 48 # 徳田 英語 48 # # # よろしくおねがいします。 # # # 各科目の最高点を名前つきで取得する(_最高点ならび) :- findsetof(_科目,テーブルA(_,_科目,_),_科目ならび), findall([_最高点氏名,_科目2,_最高点],( member(_科目2,_科目ならび), findmax([_点数,_名前2],テーブルA(_名前2,_科目2,_点数),[_最高点,_最高点氏名])), _最高点ならび). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/369 # # 会社コード|部署コード|課コード|給料 # # というテーブルがあったとき、 # GROUP BY 会社コード , 部署コード # で部署毎の給料合計を出したいけど、 # 抽出結果の列には課コードも含めたい、 # というときってどうしたら良いのでしょうか? # イメージは↓の感じです。 # A会社|B部署|C課|100万円 # A会社|B部署|D課|100万円 # A会社|E部署|F課|500万円 # A会社|E部署|G課|500万円 # '抽出結果に課コードを加えた、会社コード・部署コードで集約した給与合計ならび'(_給与合計ならび) :- findsetof([_会社コード,_部署コード,_課コード],給料(_会社コード,_部署コード,_課コード,_),L1), findall([_会社コード,_部署コード,_課コード,_給与合計],( member([_会社コード,_部署コード,_課コード],L1), findsum(_給与,給与(_会社コード,_部署コード,_,_給与),_給与合計)),_給与合計ならび). % 以下のサイトは # 出典:: http://hibari.2ch.net/test/read.cgi/db/1274791771/364 # # 商品コード|売上店舗|売上個数 # # というテーブルから、 # 店舗毎の売上をまとめた列を追加した以下のようなテーブルを作りたいです。 # # 商品コード|店舗a売上個数|店舗b売上個数|店舗c売上個数| # # 現在は店舗毎の売上を集計したテーブルを別に作って、それを結合させて作っていますが、それ以外で単一のsqlで書く場合どうなるでしょうか? # # 簡単かと思ったら思いつきません。。 # お願いします。 # # # '商品コード|店舗a売上個数|店舗b売上個数|店舗c売上個数|'(_商品番号・売上店舗別売上合計ならび) :- findsetof(_商品番号,商品売上(_商品番号,_,_),L1), findall([_商品番号|_店舗別売上合計ならび],( member(_商品番号,L1), findall(_店舗別売上合計ならび,( member(_売上店舗,[a,b,c]), findsum(_売上個数, 商品売上(_商品番号,_売上店舗,_売上個数), _店舗別売上合計ならび))), _商品番号・売上店舗別売上合計ならび). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1279286575/74 # # 【質問テンプレ】 # [1] 授業単元:情報処理課題 # [2] 問題文(含コード&リンク):英語の文章で構成されるテキストファイルに対して、その中に含まれる総文字数と異なる文字ごとの出現回数とを数え上げよ。 # [3.3] 言語:C # [4] 期限:2010年07月19日00:00まで # [5] その他の制限:Xcodeを使用しています。読み込むファイルは"/Users/user/Desktop/data.txt"で。 # # 似たようなプログラムを作った時は「数列を入力し総文字数と数字ごとに出現回数とを数え上げグラフで表示」というような課題で # 数字だったので0〜9までを表示することが簡単に出来ましたがアルファベットなのでa-zをどう表示したものか # またstrlenだと半角空白も数えてしまうので総"文字"数とずれてくるのではないかと悩んでいます。 # よろしくお願いします。 # # 英語の文章で構成されるテキストファイルに対して、その中に含まれる総文字数と異なる文字ごとの出現回数とを数え上げる(_総文字数,_文字ごとの出現度数ならび) :- get_chars('/Users/user/Desktop/data.txt',Chars), length(Chars,_総文字数), findsetof(C,member(C,Chars),L1), findall([C,_出現度数],(member(C,L1),count(member(C,Chars),_出現度数)),_文字ごとの出現度数ならび). findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1276810079/920 # # [1] C言語プログラミング演習 # [2] 問題文(含コード&リンク # ATM(Automated Teller Machine; 現金自動預け払い機)システムを実現するプログラムを考える。 # # 氏名,口座番号,暗証番号,預金残高を要素とする構造体を宣言し, 512人分の口座が作成可能なようにせよ.また,初期値として次のように構造体の内容を設定せよ. # # 立命太郎の口座番号は1234で,預金残高を1,234,560円に設定する. # 野路花子の口座番号は5678で,預金残高を987,600円に設定する. # 衣笠一郎の口座番号は9012で,預金残高を538,600円に設定する. # 暗証番号は口座番号に1111を足して10000で割った余りに設定する. # ここで暗証番号は、口座番号を引数としてとり、それに1111を足して10000で # 割った余りを計算する関数を作成して設定すること. # 上記の方法で初期値を設定し、設定された3人の預金残高を画面へ出力する # プログラムを作成せよ.ただし、ひとり分の預金残高を表示する関数を作成して、 # これを繰り返し使って3人の預金残高を出力すること. # # % ./initAccount # 預金残高は次のとおりです. # 立命太郎 (1234) 1234560 円 # 野路花子 (5678) 987600 円 # 衣笠一郎 (9012) 538600 円 # % 預金口座の初期設定(_ファイル) :- w3c('http://pc12.2ch.net/test/read.cgi/tech/1276810079/920',Lines), append(_,[Line|R],Lines), split(Line,[の口座番号は,'で,貯金残高を,円に設定する.'],[_氏名,_口座番号,_預金残高]), assertz(預金口座(_氏名,_口座番号,_預金残高)), _暗証番号 is (_口座番号 + 1111) mod 10000, assertz(預金口座暗証番号(_口座番号,_暗証番号)), R = [],!. 預金口座の初期設定(_). 設定された3人の預金残高を画面へ出力する :- findsetof(_口座番号,預金口座(_,_口座番号,_),_口座番号ならび), write('預金残高は次のとおりです.\n'), append(_,[_口座番号|R],_口座番号ならび), ひとり分の預金残高を表示する(_口座番号), R = []. ひとり分の預金残高を表示する(_口座番号) :- 預金口座(_氏名,_口座番号,_預金残高), write_formatted('%t (%t) %t 円\n',[_氏名,_口座番号,_預金残高]),!. % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1276810079/887 # # [1] 授業単元:プログラミング演習 # [2] 問題文(含コード&リンク): # fgets() を使って50文字以下の文字列を入力し,文字列中の各 # 文字の出現回数を数えるプログラムを作成せよ。 # 実行例 # 文字列は? abcdef,abb(ccc110) # a : 2 # b : 3 # c : 4 # d : 1 # e : 1 # f : 1 # , : 1 # ( : 1 # 1 : 2 # 0 : 1 # ) : 1 # '50文字以下の文字列を入力し,文字列中の各文字の出現回数を数える' :- '50文字以下の文字列を入力し'(_50文字以下の文字列), 文字列中の各文字の出現回数を数える(_50文字以下の文字列,_文字ごとの出現回数ならび), 文字ごとの出現回数を表示する(_文字ごとの出現回数ならび). '50文字以下の文字列を入力し'(_50文字以下の文字列) :- get_line(_50文字以下の文字列), length(_50文字以下の文字列,_文字数), _文字数 =< 50. 文字列中の各文字の出現回数を数える(_文字列,_出現回数ならび) :- どんな文字が出現したかならびに数え上げる(_文字列,_重複を許さない文字ならび), 各文字の出現回数を数える(_文字列,_重複を許さない文字ならび,_出現回数ならび). どんな文字が出現したかならびに数え上げる(_文字列,_重複を許さない文字ならび) :- findsetof(_文字,( sub_atom(_文字列,_,1,_,_文字)), _重複を許さない文字ならび). 各文字の出現回数を数える(_文字列,_重複を許さない文字ならび,_出現回数ならび) :- findall([_出現回数,_文字],( append(_,[_文字|_],_重複を許さない文字ならび), count(sub_atom(_文字列,_,1,_,_文字),_出現回数)), _出現回数ならび). 文字ごとの出現回数を表示する(_文字ごとの出現回数ならび) :- append(_,[[_出現回数,_文字]|R],_文字ごとの出現回数ならび), writef('%t : %t\n',[_文字,_出現回数]), R = []. % % 文字列をならび(リスト)に変換しない場合は、非決定性述語sub_atom/5を使う。 % % 出現回数と文字の並びがひっくり返っているのは整列を求められた場合への備えだが、 % 好ましいことではないかも知れない。 % % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1274791771/243 # # プログラム言語で以下の集約を定義しなさい。  # SELECT CASE pref_name #        WHEN '徳島' THEN '四国' #        WHEN '香川' THEN '四国' #        WHEN '愛媛' THEN '四国' #        WHEN '高知' THEN '四国' #        WHEN '福岡' THEN '九州' #        WHEN '佐賀' THEN '九州' #        WHEN '長崎' THEN '九州' #        ELSE 'その他' END AS district, #     SUM(population) #  FROM PopTbl #  GROUP BY CASE pref_name #        WHEN '徳島' THEN '四国' #        WHEN '香川' THEN '四国' #        WHEN '愛媛' THEN '四国' #        WHEN '高知' THEN '四国' #        WHEN '福岡' THEN '九州' #        WHEN '佐賀' THEN '九州' #        WHEN '長崎' THEN '九州' #        ELSE 'その他' END; 地方で集約する(_地方,_人口) :- findsetof(_地方,( 'PopTbl'(_pref_name,_population), 地方(_地方,_pref_name)), L1), append(_,[_地方|_],L1), findsum(_population,( 'PopTbl'(_pref_name,_population), 地方(_地方,_pref_name)), _人口). 地方(四国,徳島). 地方(四国,香川). 地方(四国,愛媛). 地方(四国,高知). 地方(九州,福岡). 地方(九州,佐賀). 地方(九州,長崎). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1274791771/231 # # tbl1にnum1,num2,id1,id2,id3 # tbl2にid,name,ssというフィールドがあるとして # SELECT name, num1, num2, id1, id2, id3, time FROM tbl1, tbl2 # WHERE num1 = 1 # AND id1 = ( SELECT id FROM tbl2 WHERE ss = "monga") # 上記のようなSQLを # 特定のフィールドが他の行と重複してたら抜かすというのはどうやればいいでしょうか? # 単にdistinctつけるだけだとどれかひとつでも重複していなかったら抽出されますよね。 # id1,id2,id3が他のレコードのid1,id2,id3と重複してたら # 検索結果に入れないみたいな感じにしたいのですが。 # MYSQLです。 'id1,id2,id3が他のレコードのid1,id2,id3と重複してたら検索結果に入れない'([_name,_num1,_num2,_id1,_id2,_id3]) :- findall([_name,_num1,_num2,_id1,_id2,_id3],( tbl1(num1,_num2,_id1,_id2,_id3), num1 = 1, tbl2(id1,_name,monga)), L1), findsetof([_id1,_id2,_id3],member([_,_,_,_id1,_id2,_id3],L1),L2), findall([_id1,_id2,_id3],( count((member([_id1,_id2,_id3],L2),1)), L2), member([_name,_num1,_num2,_id1,_id2,_id3],L1), member([_id1,_id2,_id3],L2). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1274791771/139 # # 期間の抽出について相談です。 # 元情報 # ID    START    END # -----   -----    ----- # 10    2010/06/01  2010/06/12 # 10    2010/06/13  2010/06/14 # 10    2010/06/15  NULL # 20    2010/06/01  2010/06/11 # 20    2010/06/13  2010/06/15 # ↓ # 欲しい情報 # ID    START    END # -----   -----    ----- # 10    2010/06/01  NULL # 20    2010/06/01  2010/06/11 # 20    2010/06/13  2010/06/15 # # ・開始日、終了日の期間重複はなし # ・IDごとにデータを抽出。抽出単位は連続している期間の最小開始日と最大終了日 # ・期間は綺麗に連続(ID=10)することもあれば非連続することもある(ID=20) # # アドバイス願います。 # # 'IDごとにデータを抽出。抽出単位は連続している期間の最小開始日と最大終了日' :- findsetof(_ID,期間(_ID,_期間下限,_期間上限),L1), findall([_ID,_最小開始日,_最大終了日],( member(_ID,L1), findmin([_ID,_開始日],開始日(_ID,_開始日),_最小開始日), findmax([_ID,_終了日],終了日(_ID,_終了日),_最大終了日)), L). write('ID START END \n----- ----- ----- \n'), append(_,[[_ID,_Start,_End]|R],L), write_formatted('%t %t %t\n',[_ID,_Start,_End]), R = []. 開始日(_ID,_開始日) :- 期間(_ID,_開始日,_). 終了日(_ID,_終了日) :- 期間(_ID,_開始日,_終了日),\+(_終了日='NULL'). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1274791771/96 # # 教えてください # table aから(dept,place)でのくくりでcount の次のレスに示すようにtop3を抽出したいです # # table a # dept|place|ext|count # aaaa|aaaaa|jar|10 # aaaa|aaaaa|com|4 # aaaa|aaaaa|scr|20 # aaaa|aaaaa|exe|80 # aaaa|aaaaa|bat|2 # aaaa|bbbbb|ace|10 # aaaa|bbbbb|arj|4 # aaaa|bbbbb|zip|20 # aaaa|bbbbb|rar|80 # aaaa|bbbbb|lzh|2 # bbbb|aaaaa|mdb|10 # bbbb|aaaaa|xls|4 # bbbb|aaaaa|ppt|20 # bbbb|aaaaa|doc|80 # bbbb|aaaaa|txt|2 # bbbb|bbbbb|gif|10 # bbbb|bbbbb|png|4 # bbbb|bbbbb|jpg|20 # bbbb|bbbbb|bmp|80 # bbbb|bbbbb|tif|2 # ↓ # aaaa|aaaaa|exe|80 # aaaa|aaaaa|scr|20 # aaaa|aaaaa|jar|10 # aaaa|bbbbb|rar|80 # aaaa|bbbbb|zip|20 # aaaa|bbbbb|ace|10 # bbbb|aaaaa|doc|80 # bbbb|aaaaa|ppt|20 # bbbb|aaaaa|mdb|10 # bbbb|bbbbb|bmp|80 # bbbb|bbbbb|jpg|20 # bbbb|bbbbb|gif|10 # 'table aからdept,placeのくくりでcountのtop3を抽出' :-     findsetof([_dept,_place],a(_dept,_place,_exit,_count)),     findall(X,findrsort([_count],a(_dept,_place,_ext,_count),X),L),     for(1,N,3),     list_nth(N,L,X),     write_formatted('%t|%t|%t|%t\n',X),     N = 3,     fail. 'table aからdept,placeのくくりでcountのtop3を抽出'. % findrsort/3,findsetof/2 は http://nojiriko.asia/prolog/findsort.html 参照 % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1274791771/39 # # # maindata # ----------------------------- # main_id | main_name | junle # ----------------------------- # 1000001 | aaaaaaaaa | 1 # 1000002 | bbbbbbbbb | 2 # 1000003 | ccccccccc | 1 # 1000004 | ddddddddd | 3 # 1000005 | eeeeeeeee | 1 # # itemdata # -------------------- # item_id | item_name # -------------------- # 9000001 | AAAAAAAAA # 9000002 | BBBBBBBBB # 9000003 | CCCCCCCCC # 9000004 | DDDDDDDDD # 9000005 | EEEEEEEEE # # itemlist # ------------------ # main_id | item_id # ------------------ # 1000001 | 9000001 # 1000001 | 9000004 # 1000002 | 9000002 # 1000002 | 9000005 # 1000004 | 9000002 # 1000004 | 9000004 # 1000004 | 9000005 # # という3つのテーブルがある場合に、maindata.junle='1'を条件に # main_id | main_name | itemlists # ---------------------------------------------------- # 1000001 | aaaaaaaaa | AAAAAAAAA DDDDDDDDD # 1000003 | ccccccccc | # 1000004 | eeeeeeeee | BBBBBBBBB DDDDDDDDD EEEEEEEEE # ---------------------------------------------------- # ※itemlistsは空白で連結 # # という結果を求めたいと思います。 # サブクエリを利用して一度に求めることは可能でしょうか? # それとも、アプリケーション側でループの際に都度itemlistsを生成する必要がありますでしょうか? # 'main_id | main_name | itemlists'(_main_id,_main_name,_itemlists) :- findsetof([_main_id,_main_name],( _junle='1', maindata(_main_id,_main_name,_junle)), L), member([_main_id,_main_name],L), findall(_item_name,( itemlist(_main_id,_item_id), itemdata(_item_id,_item_name)), _itemlists_1), concat_atom(_itemlists_1,' ',_itemlists). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1274791771/29 # # まったくわからないのです教えてください・・ # # 1、名前はわかっているが、コードが不明な商品の受注明細を照会するSELECT文を記述せよ。 # 副照会:商品名からコードを求めるSELECT文 # 主照会:商品コードから商品の受注明細を照会するSELECT文 # # 2、平均受注個数を超える商品に仕入れ先を照会するSELECT文を記述せよ。 # 副照会:商品の平均受注個数を求めるSELECT文 # 主照会:商品コード別に受注個数合計を求め、受注個数合計 > 平均受注個数であれば、仕入れ先を表示 # # 3、1月と2月に\50,000以上の注文があった顧客からの3月受注額を照会するSELECT文を記述せよ。 # 副照会:4月と5月に受注額合計が共に50000以上であるという条件をみたす顧客を照会 # 主照会:顧客別に6月の受注額合計を求めるSELECT文。 # # よろしくお願いいたします・ # 名前はわかっているが、コードが不明な商品の受注明細を照会する(_商品名,_受注明細) :- 商品名(_商品コード,_商品名), 受注明細(_顧客コード,_扱店コード,_受注日,_納品予定日,_商品コード,_荷姿,_数量,_単価,_金額,_入力時刻). '1月と2月に50,000以上の注文があった顧客からの3月受注額を照会する'(_顧客コード,_受注額) :- '1月と2月に50,000以上の注文があった顧客'(_顧客コード), findsum(_金額,(受注明細(_顧客コード,_,_受注日,_,_,_,_,_,_金額,_),sub_atom(_受注日,4,2,_,'03')),_受注額). '1月と2月に50,000以上の注文があった顧客'(_顧客コード) :- '1月に50000以上の注文があった顧客'(_1月に50000以上注文があった顧客コードならび), '2月に50000以上の注文があった顧客'(_2月に50000以上注文があった顧客コードならび), 積集合(_1月に50000以上注文があった顧客コードならび,_2月に50000以上注文があった顧客コードならび,_1月と2月に50000以上の注文があった顧客コードならび), member(_顧客コード,_1月と2月に50000以上の注文があった顧客コードならび). '1月に50000以上の注文があった顧客'(_1月に50000以上注文があった顧客コードならび), findsetof(_顧客番号,(受注明細(_顧客コード,_,_受注日,_,_,_,_,_,_金額,_),sub_atom(_受注日,5,2,'01')),_1月に注文があった顧客コードならび), findall(_顧客番号,( findsum(_金額,( member(_顧客番号,_1月に注文があった顧客コードならび), 受注明細(_顧客コード,_,_受注日,_,_,_,_,_,_金額,_), sub_atom(_受注日,4,2,_,'01')), _合計金額), _合計金額 > 50000), _1月に50000以上注文があった顧客コードならび),!. '2月に50000以上の注文があった顧客'(_2月に50000以上注文があった顧客コードならび), findsetof(_顧客番号,(受注明細(_顧客コード,_,_受注日,_,_,_,_,_,_金額,_),sub_atom(_受注日,5,2,'02')), _2月に注文があった顧客コードならび), findall(_顧客番号,( findsum(_金額,( member(_顧客番号,_2月に注文があった顧客コードならび), 受注明細(_顧客コード,_,_受注日,_,_,_,_,_,_金額,_), sub_atom(_受注日,4,2,_,'02')), _合計金額), _合計金額 > 50000), _2月に50000以上注文があった顧客コードならび),!. /* 平均受注個数を超える商品に仕入れ先を照会する(_商品コード,_顧客コード) :- 商品ごとの平均受注個数を調べる(_商品ごとの平均受注個数ならび), 平均受注個数を超える商品に仕入れ先を照会する(_商品ごと平均受注個数ならび,_商品コード,_顧客コード). 商品ごとの平均受注個数を調べる(_商品ごとの平均受注個数ならび) :- findall(_商品コード,商品名(_商品コード),_商品コードならび), findsetof([_顧客番号,_商品コード], 受注明細(_顧客コード,_,_,_,_商品コード,_,_,_,_,_), _顧客コード・商品コードならび), 荷姿変換(_荷姿,_数量,_数量_1,_単価,_単価_1,_金額,_金額_1), 荷姿変換(_荷姿,_数量,_数量,_単価,_単価,_金額,_金額) :- つまり荷姿変換は行わない. つまり荷姿変換は行わない. */ % 以下のサイトは # 出典:: http://pc12.2ch.net/test/read.cgi/tech/1269438098/901 # # ../test/read.cgi/tech/1269438098/900 # こんな入力・出力例でいいの? # # Input: # # 2 # 1,1,murayama # 1,2,sugano # 3,3,koizumi # 3,4,abe # 5,5,hatoyama # 6,6,ozawa # # Output: # # #1 # Rep. Name: murayama # Rep. Attendance: 1 # Group: 001 # Group Attendance: 2 # # #2 # Rep. Name: koizumi # Rep. Attendance: 1 # Group: 003 # Group Attendance: 2 # 代表の生徒の名前、代表者の出席回数、グループメンバーの出席回数、グループの全体の出席回数の上位x番だけ出力する(_代表の生徒の名前,_代表者の出席回数,_グループメンバーの出席回数上位5位,_グループ全体の出席回数上位5位) :- findall([_代表の個人ID,_名前],生徒(_代表の個人ID,_代表の個人ID,_名前),_代表の個人ID・名前ならび), member([_代表の個人ID,_名前],_代表の個人ID・名前ならび), 代表者の出席回数(_代表の個人ID,_代表者の出席回数), グループメンバーの出席回数(_代表のID,_グループメンバーの出席回数ならび), グループメンバーの出席回数上位5位(_グループメンバーの出席回数ならび,グループメンバーの出席回数上位5位), グループ全体の出席回数(_代表のID,_グループ全体の出席回数ならび), グループ全体の出席回数上位5位(_グループ全体の出席回数ならび,グループ全体の出席回数上位5位). 代表者の出席回数(_代表の個人ID,_代表者の出席回数) :- count(出席者(_代表の個人ID),_代表者の出席回数). グループメンバーの出席回数(_代表のID,_グループメンバーの出席回数ならび) :- findsetof(_個人ID,(生徒(_代表のID,_個人ID,_),\+(_代表のID=_個人のID)),_グループメンバーならび), findall([_出席回数,_個人ID], ( member(_個人ID,_グループメンバーならび), count(出席者(_個人ID),_出席回数)), _グループメンバーの出席回数ならび),!. グループ全体の出席回数(_代表のID,_グループメンバーの出席回数ならび) :- findsetof(_個人ID,生徒(_代表のID,_個人ID,_),_グループメンバーならび), findall([_出席回数,_個人ID], ( member(_個人ID,_グループメンバーならび), count(出席者(_個人ID),_出席回数)), _グループ全体の出席回数ならび),!. グループメンバーの出席回数上位N位(N,_グループメンバーの出席回数ならび,_グループメンバーの出席回数上位5位) :- 大きい順に上位N位(N,_グループメンバーの出席回数ならび,_グループメンバーの出席回数上位5位). グループ全体の出席回数上位N位(N,_グループ全体の出席回数ならび,_グループ全体の出席回数上位5位) :- 大きい順に上位N位(N,_グループ全体の出席回数ならび,_グループ全体の出席回数上位5位). 大きい順に上位N位(L1,L) :- sort(L1,L2), reverse(L2,L3), length(L,N), append(L,_,L3),!. 大きい順に上位N位(L1,L) :- sort(L1,L2), reverse(L2,L),!. キーボードから代表者のID,個人のID,名前を入力するものとし、グループメンバーは代表者のIDでのみで関連付けされる :- キーボードから代表者のID,個人のID,名前を入力する(_代表者のID,_個人のID,_名前), assertz(生徒(_代表者のID,_個人のID,_名前)), キーボードから代表者のID,個人のID,名前を入力するものとし、グループメンバーは代表者のIDでのみで関連付けされる. キーボードから代表者のID,個人のID,名前を入力するものとし、グループメンバーは代表者のIDでのみで関連付けされる. キーボードから代表者のID,個人のID,名前を入力する(_代表者のID,_個人のID,_名前) :- get_split_line([','],[_代表者のID,_個人のID,_名前]). 出席者の入力 :- get_line(Line), atom_to_term(Line,_個人ID,_), integer(_個人ID), assertz(出席者(_個人ID)), 出席者の入力. 出席者の入力. % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/933 # # DEFENDANT  GUILT  JOROR # -----------+-------+-------- # HOGE      | 1     | FOO # HOGE      | 0     | BAR # HOGE      | 1     | BAZ # FUGA     | 1     | FOO # FUGA     | 1     | BAR # FUGA     | 1     | BAZ     (T_JUDGEテーブル) # # 上記のテーブルにDEFENDANTで絞込をかけた結果、GUILTに一つでも0がある場合 # 1行も取得せず、全部1の場合はそのまま一覧を返す場合どのようなSQLを書けば # よいでしょうか?この場合、HOGEで絞り込むと0行、FUGAなら3行と言う具合です。 # # DBMSはMySQL5.0.67です。 # # 'T_JUDGEテーブル'('HOGE',1,'FOO'). 'T_JUDGEテーブル'('HOGE',0,'BAR'). 'T_JUDGEテーブル'('HOGE',1,'BAZ'). 'T_JUDGEテーブル'('FUGA',1,'FOO'). 'T_JUDGEテーブル'('FUGA',1,'BAR'). 'T_JUDGEテーブル'('FUGA',1,'BAZ'). 'T_JUDGEテーブルにDEFENDANTで絞込をかけた結果、GUILTに一つでも0がある場合1行も取得せず、全部1の場合はそのまま一覧を返す'(_DEFENDANT,_GUILT,_JOROR) :- findsetof(_DEFENDANT,('T_JUDGEテーブル'(_DEFENDANT,_GUILT,_JOROR),\+(_GUILT=0)),L1), findsetof(_DEFENDANT,('T_JUDGEテーブル'(_DEFENDANT,_GUILT,_JOROR),_GUILT=0),L2), 差集合(L1,L2,L3), member(_DEFENDANT,L3), T_JUDGEテーブル(_DEFENDANT,_GUILT,_JOROR). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/922 # # 売上データベースがあって、主テーブルの項目は、売上番号、得意先名、日付。 # 明細テーブルの項目は、明細番号、売上番号、商品、個数。売上番号で1対多でリンクしています。 # 商品(複数)と日付を指定して、 商品名 個数計 得意先計の一覧を出力したいです。 # ただし得意先名は同名を1とカウントしたいのです。 # SELECT 明細.商品, Sum(明細.個数) AS 個数計, Count(主.得意先) AS 得意先計 # FROM 主 INNER JOIN 明細 ON 主.売上番号 = 明細.売上番号 # WHERE 主.日付 Between '5/1/2010' And '5/4/2010' # GROUP BY 明細.商品 # HAVING 明細.商品='えんぴつ' or 明細.商品='筆'; # とすると、得意先計が複数カウント(同名は1とならない)してしまいます。 # どのように書いたらよいのでしょうか。 # '商品(複数)と日付を指定して、 商品名 個数計 得意先計の一覧を出力する'(_商品ならび,_日付下限,_日付上限,X) :- findall([_商品,_個数,_得意先名],(主(_売上番号,_得意先名,_日付),明細(_明細番号,_売上番号,_商品,_個数),member(_商品,_商品ならび),_日付@>=_日付下限,_日付@=<_日付上限),_選択ならび), findsetof([_商品,_得意先名],member([_商品,_個数,_得意先名],_選択ならび),_鍵ならび), findall([_商品,_個数計,_得意先名],(member([_商品,_得意先名],_鍵ならび),findsum(_個数,member([_商品,_個数,_得意先名],_選択ならび),_個数計)),X). % 以下のサイトは findsort(_集約項,_集約対象項,P,_射影項) :- findsetof(_集約項,P), append(_集約対象項,_射影項,L1), findall(L1,P,L2), sort(L2,L3), append(_集約対象項,_射影項,L), member(L,L3). findrsort(_集約項,_集約対象項,P,_射影項) :- findsetof(_集約項,P), append(_集約対象項,_射影項,L1), findall(L1,P,L2), sort(L2,L3), reverse(L3,L4), append(_集約対象項,_射影項,L), member(L,L4). findsort(_集約対象項,P,_射影項) :- append(_集約対象項,_射影項,L1), findall(L1,P,L2), sort(L2,L3), append(_集約対象項,_射影項,L), member(L,L3). findrsort(_集約対象項,P,_射影項) :- append(_集約対象項,_射影項,L1), findall(L1,P,L2), sort(L2,L3), reverse(L3,L4), append(_集約対象項,_射影項,L), member(L,L4). findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L). findsetof(A,B) :- findall(A,B,C), setof(A,member(A,C),D), member(A,D). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/817 # # [テーブルA] # ID, AGE, GROUP # --- ---- ----- # 1 , 10, A # 2 , 20, A # 3 , 30, A # 4 , 20, B # 5 , 40, B # 6 , 60, B # 7 , 10, C # 8 , 30, C # 9 , 50, C # 10 , 70, C # # ↑のテーブルから、 # 各GROUP毎にAGEで順位付けした結果を取得したいです。 # # <結果> # # ID, AGE, GROUP, RANK # --- ---- ----- ----- # 1 , 10, A 1 # 2 , 20, A 2 # 3 , 30, A 3 # 4 , 20, B 1 # 5 , 40, B 2 # 6 , 60, B 3 # 7 , 10, C 1 # 8 , 30, C 2 # 9 , 50, C 3 # 10 , 70, C 4 # # # GROUP BYを使ってみたのですが、 # どうも見当違いのSQLになってしまって。。 # # すいませんが、どのようなSQLを書けばよいかご教示ください。 # '各GROUP毎にAGEで順位付けした結果を取得'(X) :- findsetof(Group,'テーブルA'(_,_,Group),L1), '各GROUP毎にAGEで順位付けした結果を取得'(1,L1,X). '各GROUP毎にAGEで順位付けした結果を取得'(_,[],[]) :- !. '各GROUP毎にAGEで順位付けした結果を取得'(M,[Group|R1],X) :- findall([Age,Group],'テーブルA'(_,Age,Group),L2), 整列(L2,L3), 順序づけ(M,M2,1,L3,L4), '各GROUP毎にAGEで順位付けした結果を取得'(M2,R1,Y), append(L4,Y,X). 順序づけ(M,M,_,[],[]) :- !. 順序づけ(M,MX,N,[[Age,Group]|R1],[M,Age,Group,N|R2]) :- N2 is N + 1, M2 is M + 1, 順序づけ(M2,MX,N2,R1,R2). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/789 # # [TABLE1] # # key1 key2 data # ------------------------------------ # AAA 01 zzz # AAA 02 yyy # BBB 01 xxx # BBB 03 www # CCC 02 vvv # DDD 03 uuu # # # # [TABLE2] # key1 data # ------------------------------------ # MMM 01&02 # NNN 01only # OOO 02only # # # このようなテーブルから、以下のデータを抽出したいです。 # # # # key1 key2 data1 data2 # --------------------------------------------- # AAA 01 zzz 01&02 # BBB 01 xxx 01only # CCC 02 vvv 02only # # # TABLE1のKEYはkey1とkey2です。 # このTABLE1から、各key1に対して一意にデータを抽出します。 # 抽出はkey2の値が01と02のもののみを対象とし、 # 01があれば01のデータを、なければ02のデータを引っ張ってきます(data1)。 # # さらに、各key1におけるkey2の状況?をdata2として付加したいです。 # ここではTABLE2に格納されていることにしましたが、 # 条件文で単に文字列を設定するのでも構いません。 # # SQLServer2000を使用します。 # どのようなSQLを書けばよいでしょうか? # よろしくお願いします。 # # 'TABLE1から、各key1に対してkey2の値が01と02のもののみを対象とし、01があれば01のデータを、なければ02のデータを抽出し各key1におけるkey2の状況をdata2として付加してTABLE2に追加して出力' :- findsetof(_key1,('TATLE1'(_key1,_key2,_data),key2の対象は01か02のみ(_key2)),L1), 見出し, member(_key1,L1), '01があれば01のデータを、なければ02のデータを抽出し各key1におけるkey2の状況をdata2として付加'(_key1,L2), write_formatted('%t %t %t %t\n',L2), fail. 'TABLE1から、各key1に対してkey2の値が01と02のもののみを対象とし、01があれば01のデータを、なければ02のデータを抽出し各key1におけるkey2の状況をdata2として付加してTABLE2に追加して出力'. key2の対象は01か02のみ('01') :- !. key2の対象は01か02のみ('02') :- !. '01があれば01のデータを、なければ02のデータを抽出し各key1におけるkey2の状況をdata2として付加'(_key1,X) :- findall([_key1,_key2,_data],'01があれば01のデータを、なければ02のデータを抽出し'(_key1,_key2,_data),L), 各key1におけるkey2の状況(L,X), X = [_,_,_,TABLE2data], assertz('TABLE2'(_key1,TABLE2data)),!. '01があれば01のデータを、なければ02のデータを抽出し'(_key1,'01',_data) :- 'TABLE1'(_key1,'01',_data). '01があれば01のデータを、なければ02のデータを抽出し'(_key1,'02',_data) :- 'TABLE1'(_key1,'02',_data). 各key1におけるkey2の状況([[_key1,'01',_data]],[_key1,'01',_data,'01only']) :- !. 各key1におけるkey2の状況([[_key1,'02',_data]],[_key1,'02',_data,'02only']) :- !. 各key1におけるkey2の状況([[_key1,'01',_data],[_key1,'02',_]],[_key1,'01',_data,'01&02']) :- !. 各key1におけるkey2の状況([[_key1,'02',_],[_key1,'01',_data]],[_key1,'01',_data,'01&02']) :- !. 見出し :- write('key1 key2 data1 data2 \n'-----------------------------------\n'). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/751 # # # 年月日と金額を持ったテーブルがあります。前年度合計と今年度合計を出したいのですが、 # # 年月日 金額 # 20080402 200 # 20080404 200 # 20090401 100 # 20090401 500 # 20090404 300 # # とあった場合、↓にしたいです # # 年月日 今年度合計 前年度合計 # 20090401 600 0 # 20090402 0 200 # 20090404 300 200 # # 両年度金額が無い場合は表示無しで、年月日は8桁の数値型です。 # うるう年は考慮しなくて構いません。 年月日と金額を持ったテーブルがあります。前年度合計と今年度合計を出したいのですが :- 初めに重複しない年月日ならびを取り出します(_重複しない年月日ならび), 見出しです, 重複しない年月日ならびから順に年月日を取り出し今年度合計と前年度合計を計算して表示します(_重複しない年月日ならび). 初めに重複しない年月日ならびを取り出します(_重複しない年月日ならび) :- findsetof(_年月日,テーブル(_年月日,_),_重複しない年月日ならび). 見出しです :- write_formatted('%8s %10s %10s\n',[年月日,今年度合計,前年度合計]). 重複しない年月日ならびから順に年月日を取り出し今年度合計と前年度合計を計算して表示します([]) :- !. 重複しない年月日ならびから順に年月日を取り出し今年度合計と前年度合計を計算して表示します([_年月日|R]) :- _前年同日 is _年月日 - 10000, ある年月日の金額合計(_年月日,_今年度合計), その前年同日の金額合計(_前年同日,_前年度合計), 年月日と今年度合計と前年度合計を表示します(_年月日,_今年度合計,_前年度合計), 重複しない年月日ならびから順に年月日を取り出し今年度合計と前年度合計を計算して表示します(R). ある年月日の金額合計(_年月日,_金額合計) :- findsum(_金額,(テーブル(_年月日,_金額),_金額合計). その前年同日の金額合計(_前年同日,_前年同日金額合計) :- findsum(_前年同日金額,(テーブル(_前年同日,_前年同日金額),_前年同日金額合計). 年月日と今年度合計と前年度合計を表示します(_年月日,_今年度合計,_前年度合計) :- write_formatted('%t %10.0f %10.0f\n',[_年月日,_今年度合計,_前年度合計]). % 以下のサイトは # 出典:: http://pc11.2ch.net/test/read.cgi/db/1252492296/713 # # # A B C # - - - # 1 3 a # 1 5 b # 2 8 c # 2 4 d # 2 6 e # 3 3 f # 3 1 g # # 上記のようなSAMPLEテーブルがあるとき、 # AごとにBが最大となるレコードのCを得たい、 # つまり、抽出結果を下記のようにしたいと考えています。 # # A C # - - # 1 b # 2 c # 3 f 'SAMPLE'('1','3','a'). 'SAMPLE'('1','5','b'). 'SAMPLE'('2','8','c'). 'SAMPLE'('2','4','d'). 'SAMPLE'('2','6','e'). 'SAMPLE'('3','3','f'). 'SAMPLE'('3','1','g'). 'AごとにBが最大となるレコードのCを得る'(X,Y) :- findsetof(A,'SAMPLE'(A,_,_),L), member(A,L), findmax([B,A,C],'SAMPLE'(A,B,C),[_,X,Y]). findsetof(A,B,C) :- findall(A,B,L), setof(A,member(A,L),C). findmax(A,P,X) :- findall(A,P,L), sort(L,L2), last(L2,X). % 以下のサイトは % *** user: findsetof / 3 *** findsetof(A,B,L) :- findall(A,B,C), setof(A,member(A,C),L) . % *** user: findsetof / 3 *** findsetof(A,B,L) :- B =.. [_|L1], setof(A,L1 ^ B,L). % *** user: findsetof / 3 *** findsetof(A,B,L) :- term_variables(B,VL), setof(A,VL ^ B,L)