首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSExpression遵守子查询NSPredicate

NSExpression遵守子查询NSPredicate
EN

Stack Overflow用户
提问于 2013-07-11 19:00:05
回答 1查看 1.9K关注 0票数 5

假设我有两个实体,一个Person和一个Transaction

PersonTransaction具有多对多关系,而Transaction entity具有amountdate。我的目标是有一个基于PersonNSFetchRequest,但我只想知道在特定日期和交易额的SUM之间有交易的人。

我的代码看起来像这样:

代码语言:javascript
复制
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 <= %@).@count > 0", self.startDate, self.endDate];
self.sumAmountFetchRequest.propertiesToFetch = @[@"name", description];

一切似乎都很好但是..。当我查看生成的SQL查询时,它看起来如下所示:

代码语言:javascript
复制
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并不尊重创建的fetchRequest的NSPredicate

有没有可能让表达式也遵守附加到fetchRequest的谓词?或者,既然NSExpression是独立的,我应该给它附加另一个谓词吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-11 22:17:42

我没有任何东西来支持我自己的答案,但在与此斗争了几个小时之后。我认为这并不是因为NSExpression不尊重fetchRequest的NSPredicate,而是因为fetchRequest的谓词是一个子查询。

代码语言:javascript
复制
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,它就能完美地工作。

代码语言:javascript
复制
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将为

代码语言:javascript
复制
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 

干杯,

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17591616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档