このディレクトリの索引
http://toro.2ch.net/test/read.cgi/db/1343899481/212
#  質問です。 
#  開始地点を表すカラム start_point と終了地点を表すカラム end_point があり、その距離は 
#  ST_Distance(ST_GeographyFromText(ST_AsText(start_point)), ST_GeographyFromText(ST_AsText(end_point))) 
#  で計算できます。 
#  それで、 
#  ・select で距離を計算するときは round() するけど 
#  ・order by でソートする時は round() なしで(つまりfloatのまま)ソートする 
#  ということをしたいです。 
#  SQLはこんな感じになるんですけど、 
#  select round(ST_Distance(ST_GeographyFromText(ST_AsText(start_point)), ST_GeographyFromText(ST_AsText(end_point)))) as distance 
#  from geo_data 
#  order by ST_Distance(ST_GeographyFromText(ST_AsText(start_point)), ST_GeographyFromText(ST_AsText(end_point))) 
#  これだと距離の計算が二重に行われてしまい、無駄です。 
#  これを、距離の計算を二重に行わずに意図した通りのSQLを発行することはできますか。 
#  よろしくお願いします。 
#  環境:PostgreSQL 9.1 
#   

テーブル定義(geo,1,id).
テーブル定義(geo,2,start_point).
テーブル定義(geo,3,end_point).


'開始地点を表すカラム start_point と終了地点を表すカラム end_point があり、その距離を小さい順に取り出す(距離を四捨五入)'(_start_point,_end_point,_distance) :-
        テーブル述語を得る(geo,[start_point,end_point],[_start_point,_end_point],P),
        四捨五入しない距離で整列(P,_start_point,_end_point,L2),
        member([_distance_1,_start_point,_end_point],L2),
        四捨五入(_distance_1,_distance).

テーブル述語を得る(_テーブル名,_カラムならび,_カラム変数ならび,_テーブル述語) :-
        findall(_,(
                    テーブル定義(テーブル名,_,_)),
               L,
        カラム変数ならびを得る(_テーブル名,_カラムならび,_カラム変数ならび,L),
        _テーブル述語 =.. [_テーブル名|L].

カラム変数ならびを得る(_テーブル名,_カラムならび,[],L) :- !.
カラム変数ならびを得る(_テーブル名,[_カラム|R1],[_カラム変数|R2],L) :-
        テーブル定義(_テーブル名,Nth,_カラム),
        nth1(Nth,L,_カラム変数),
        カラム変数ならびを得る(_テーブル名,R1,R2,L).

四捨五入しない距離で整列(P,_start_point,_end_point,L2) :-
        findall([_distance,_start_point,_end_point],(
                    _テーブル述語,
                    _distance is _end_point - _start_point),
                L1),
        整列(L1,L2).

四捨五入(A,B) :-
        B is round(A).