[Mac][iOS] NSPredicate - 1対多関連のエンティティの検索条件見本(集計関数使用)

2011年1月13日木曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

[前回] Cocoaの日々: [Mac][iOS] NSPredicate - 1対多関連のエンティティの検索条件見本

お題


今回は最も新しい本の発売日が指定した日以前の著者一覧を取得する、という条件を作ってみる。例えば 2010年10月2日を指定した場合、最も新しい本が 10月2日以前の著者が該当する。11月1日に本を発売している著者はヒットしない。


条件見本


"最も新しい" 日付を条件に使うために max() 関数を使う。
NSPredicate* p = [NSPredicate predicateWithFormat:@"max(books.date) <= %@", date];
集計関数 max() を使うので ANY は必要ない。 発行される SQLはこんな感じ。
SELECT 0, t0.Z_PK FROM ZAUTHOR t0 WHERE
 (SELECT MAX(t1.ZDATE)  FROM ZBOOK t1
   WHERE (t0.Z_PK = t1.ZAUTHOR) ) <= ?
サブクエリーで子テーブルBOOKから最も新しい日付を抽出し、それと条件を比較している。

なお NSPredicate には NONE というキーワードも用意されている。
Predicate Programming Guide: Predicate Format String Syntax

これを使うと下記のようにも書けそうである。
NSPredicate* p = [NSPredicate predicateWithFormat:@"NONE books.date > %@"];
指定日時よりも新しい発売日が無いと意味(=最も新しい発売日が指定日時以前)。
ただ実際には意図通りには動かない。SQLを見ると単純に NOT が付くだけのようだ。
SELECT DISTINCT 0, t0.Z_PK FROM ZAUTHOR t0
  JOIN ZBOOK t1 ON t0.Z_PK = t1.ZAUTHOR
  WHERE  NOT (t1.DATE > ?)


NSPredicate 内で利用可能な関数


NSPredicate で使える関数は max()の他、count, min, sum などがある。 以下、Predicate Programming Guide: BNF Definition of Cocoa Predicates の Function Name から転載。
function_name ::= "sum" | "count" | "min" | "max"
    | "average" | "median" | "mode" | "stddev"
    | "sqrt" | "log" | "ln" | "exp"
    | "floor" | "ceiling" | "abs" | "trunc"
    | "random" | "randomn" | "now"
count, min などの集計関数の他、sqrt, log など数値変換用の関数も用意されている。

Responses

Leave a Response

人気の投稿(過去 30日間)