NSPredicate等同于SQL的GROUP BY

时间:2011-07-27 04:50:02

标签: objective-c ios core-data nspredicate

简化: 名为cards的表中有3列。

id packTitle term

id是一个列 - 从0到100的整数

packTitle - 描述包的字符串,假设有3种包PACK1,PACK2,PACK3

term - 101个项目的不同未分类名称。

通过SQL语句

select packTitle from cards group by packTitle;

我可以获得3个项目的清单。

你能否建议NSPredicate相当于SQL语句GROUP BY。我需要在UITableView中填充一个数组。

2 个答案:

答案 0 :(得分:15)

CoreData是一个对象图管理框架,而不是SQL数据存储。因此,您应该 - 尽可能快地 - 让自己摆脱SQL思维模式。 NSPredicate旨在作为对象图中限定对象的无意外谓词。因此,您可以获取与查询匹配的所有对象,但这与对这些结果进行分组不同。如果要进行聚合操作,请使用键值编码collection operators。在引擎盖下,Core Data 可以将这些转换为合理的SQL,但这只是一个实现细节。

在这种情况下,您可以使用

获取一组唯一的packTitle
[myCards valueForKeyPath:@"@distinctUnionOfObjects.packTitle"];

将为您提供packTitle集合中不同的myCards值集合。如果您想要核心数据存储中的所有卡,则必须对所有cards运行查询,然后应用此收集操作。

另一种方法是创建一个PackInformation实体,或者包含title属性的实体。然后,您可以在数据存储中只有3个这样的实体,从适当的包实体引用它们。获取所有三个(或任何最终数字)并获得他们的头衔是微不足道的。

正如其他人所说的那样,如果您尝试做的事情是从关系数据集进行基本报告,那么最好直接使用SQLite。这一切都取决于您从Core Data获得的其他好处。

答案 1 :(得分:2)

假设您正在使用CoreData ...根据Apple Documentation

  

您无法将“任意”SQL查询转换为   谓词或获取请求。例如,没有办法转换   一个SQL语句,如

SELECT t1.name, V1, V2
    FROM table1 t1 JOIN (SELECT t2.name AS V1, count(*) AS V2
        FROM table2 t2 GROUP BY t2.name as V) on t1.name = V.V1
     

进入获取请求。那么你必须获取感兴趣的对象   要么直接使用结果执行计算,要么使用   数组运算符。

如果你需要做这样的复杂查询,你最好使用SQLite。