NSPredicate是类似于SQL中GROUP BY的东西。

11

简化一下:

有一个名为cards的表,包含3列。

id:该列为整数,从0到100。

packTitle:该列为字符串,描述了三种类型的包:PACK1、PACK2和PACK3。

term:该列为101个不同、未排序的名称。

使用SQL语句:

select packTitle from cards group by packTitle;

我可以获取一个包含3个项目的列表。

您能否建议与SQL语句GROUP BY等效的NSPredicate?我需要获取一个数组以在UITableView中填充。

2个回答

16

CoreData是一个对象图管理框架,而不是SQL数据存储。因此,你应该尽快摆脱SQL思维方式。NSPredicate旨在作为对象图中限定对象的谓词。因此,你可以获取所有符合查询条件的对象,但这并不等同于对这些结果进行分组。如果你想执行聚合操作,请使用键值编码的集合运算符。在底层,Core Data可能会将其转换为合理的SQL,但这仅是一种实现细节。

在这种情况下,你可以通过以下方式获取唯一的packTitle值集:

[myCards valueForKeyPath:@"@distinctUnionOfObjects.packTitle"];

这将为您提供myCards集合中packTitle值的不同集合。如果您想要针对Core Data存储中的所有卡片进行此操作,则必须查询所有cards,然后应用此集合操作。

另一种方法是创建一个PackInformation实体或类似实体,其中包含一个title属性。然后,您可以只在数据存储中拥有这三个实体,并从适当的包实体中引用它们。轻松获取所有三个(或最终数量)并获得它们的标题。

正如其他人所说,如果您正在尝试从关系数据集中生成报表,您可能更好地使用纯SQLite。这完全取决于您从Core Data中获得了多少其他好处。


非常感谢您提供的详细信息,特别感谢您对我的问题的关注。看来我需要学习键值编码才能理解您的答案。同时,删除所有名为PACK1的packTile卡片也很有趣。希望我能在这个方向上找到答案。 - Michael
NSPredicate本身与Core Data无关。它可以与数组和其他数据库(如Realm)一起使用。这就是为什么这是一个有效的问题,与SQL进行比较也完全没有问题。 - brainray

3
假设您正在使用CoreData...根据苹果文档的说明。

You cannot necessarily translate “arbitrary” SQL queries into predicates or fetch requests. There is no way, for example, to convert a SQL statement such as

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

into a fetch request. You must fetch the objects of interest, then either perform a calculation directly using the results, or use an array operator.

如果您需要执行像这样的复杂查询,那么最好使用SQLite。


谢谢您的回复。那么我必须处理这些结果。 - Michael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接