2013-07-11 16 views
5

私は2つのエンティティ、PersonTransactionがあるとします。NSExpressionはサブクエリを尊重しますNSPredicate

PersonTransactionTransactionエンティティと対多の関係がamountdateを持っています。私の目標はPersonに基づいてNSFetchRequestでしたが、特定の日付と取引金額のSUMとの取引がある人のみを知りたいと思っています。

のように私のコードが見えます:

だから、
SELECT t0.ZPERSONID, t0.ZNAME, 
    (SELECT TOTAL(t2.ZAMOUNT) FROM ZTRANSACTION t2 WHERE (t0.Z_PK = t2.ZPERSON)) 
FROM ZPERSON t0 
WHERE (SELECT COUNT(t1.Z_PK) FROM ZTRANSACTION t1 WHERE (t0.Z_PK = t1.ZPERSON AND ((t1.ZDATE >= ? AND t1.ZDATE <= ?)))) > ? 

、それはNSExpressionようだ:すべては、私はSQLクエリを見たときに生成、それがどのように見える細かいようだが...

NSExpression *amountKeyPath = [NSExpression expressionForKeyPath:@"transactions.amount"]; 
NSExpression *sumAmountExpression = [NSExpression expressionForFunction:@"sum:" arguments:@[amountKeyPath]]; 

// Create the expression description for that expression. 
NSExpressionDescription *description = [[NSExpressionDescription alloc] init]; 
[description setName:@"sum"]; 
[description setExpression:sumAmountExpression]; 
[description setExpressionResultType:NSDecimalAttributeType]; 

// Create the sum amount fetch request, 
self.sumAmountFetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"]; 
self.sumAmountFetchRequest.resultType = NSDictionaryResultType; 
self.sumAmountFetchRequest.predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(transactions, $t, $t.date >= %@ AND $t.date <= %@)[email protected] > 0", self.startDate, self.endDate]; 
self.sumAmountFetchRequest.propertiesToFetch = @[@"name", description]; 

宣言された、fetchRequestのNSPredicateを尊重しません。

式をfetchRequestに付加された述語にも適用できますか?あるいは、NSExpressionがそれ自身で立っているので、私はそれに別の述語を付けるべきですか?

+0

SQLiteの文は私にはよさそうでしょう。述語は最後の "WHERE"に変換され、文全体に適用されます。期待した結果が得られますか? –

+0

いいえ、私はその人に属するトランザクションの量を得ました(時間枠に限定されません - WHERE句) – Rpranata

+0

OK、今、私はあなたが意味することを理解し、上記のコメントは間違っています。 –

答えて

5

私は自分の答えを裏付けるものは何も持っていませんが、数時間苦労しています。 NSExpressionがfetchRequestのNSPredicateを尊重しているわけではなく、fetchRequestの述語がサブクエリであるという事実よりも、それが重要であると私は考えました。

SELECT t0.ZPERSONID, t0.ZNAME, 
    (SELECT TOTAL(t2.ZAMOUNT) FROM ZTRANSACTION t2 WHERE (t0.Z_PK = t2.ZPERSON)) 
FROM ZPERSON t0 
WHERE 
    (SELECT COUNT(t1.Z_PK) FROM ZTRANSACTION t1 WHERE (t0.Z_PK = t1.ZPERSON AND ((t1.ZDATE >= ? AND t1.ZDATE <= ?)))) > ? 

ので、述語のサブクエリは本当に私が欲しいWHERE句に変換されていません。代わりにJOINを作成していればうまくいくと思います。

私の解決策は、他の方法で動作させることです。代わりにTransactionからfetchRequestを作成すると、完全に機能します。

NSExpression *amountKeyPath = [NSExpression expressionForKeyPath:@"amount"]; 
NSExpression *sumAmountExpression = [NSExpression expressionForFunction:@"sum:" arguments:@[amountKeyPath]]; 

// Create the expression description for that expression. 
NSExpressionDescription *description = [[NSExpressionDescription alloc] init]; 
[description setName:@"sum"]; 
[description setExpression:sumAmountExpression]; 
[description setExpressionResultType:NSDecimalAttributeType]; 

// Create the sum amount fetch request, 
self.sumAmountFetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Transaction"]; 
self.sumAmountFetchRequest.resultType = NSDictionaryResultType; 
self.sumAmountFetchRequest.predicate = [NSPredicate predicateWithFormat:@"date >= %@ AND date <= %@", self.startDate, self.endDate]; 
self.sumAmountFetchRequest.propertiesToFetch = @[@"person.name", description]; 
self.sumAmountFetchRequest.propertiesToGroupBy = @[@"person.name"]; 

これは完全に機能します。 "person.name"でグループ化して、sum:を使用する必要があります。

生成されたSQLは

SELECT t1.ZPERSONID, total(t0.ZAMOUNT) 
FROM ZTRANSACTION t0 
     LEFT OUTER JOIN ZPERSON t1 ON t0.ZPERSON = t1.Z_PK 
WHERE (t0.ZDATE >= ? AND t0.ZDATE <= ?) GROUP BY t1.ZPERSONID 

乾杯、

関連する問題