NSPredicate 相当于 SQL 的 GROUP BY

发布于 2024-11-26 15:51:33 字数 365 浏览 0 评论 0原文

简化一下: 名为卡片的表中有 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 中。

To simplify:
There are 3 columns in a table named cards.

id packTitle term

id is a column - integers from 0.....100

packTitle - string describing packs, lets say there are 3 kinds of pack PACK1, PACK2, PACK3

term - different unsorted names of 101 items.

by SQL statement

select packTitle from cards group by packTitle;

I can get list of 3 items.

Could you suggest NSPredicate equivalent of SQL statement GROUP BY. I need to get an array to populate in UITableView.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

兮子 2024-12-03 15:51:33

CoreData 是一个对象图管理框架,而不是 SQL 数据存储。因此,您应该尽快摆脱 SQL 思维模式。 NSPredicate 旨在作为对象图中限定对象的谓词(毫不奇怪)。因此,您可以获取与查询匹配的所有对象,但这与对这些结果进行分组不同。如果要进行聚合操作,请使用键值编码的 集合运算符。在底层,Core Data可能将这些转换为合理的 SQL,但这只是一个实现细节。

在这种情况下,您可以获得一组唯一的 packTitle 值,

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

这些值将为您提供 myCards 集合中的一组不同的 packTitle 值。如果您希望核心数据存储中的所有卡都执行此操作,则必须对所有卡运行查询,然后应用此收集操作。

另一种方法是创建一个 PackInformation 实体,或包含 title 属性的实体。然后,您可以在数据存储中仅保留其中 3 个实体,并从相应的包实体中引用它们。获取所有三个(或无论最终数字是什么)并获得它们的标题是很简单的。

正如其他人所说,如果您想要做的基本上是从关系数据集进行报告,那么您最好直接使用 SQLite。这完全取决于您从 Core Data 获得多少其他好处。

CoreData is an object graph management framework, not a SQL data store. Thus, you should—as quickly as possible—get yourself out of the SQL mindset. NSPredicate is intended as a—no surprise—predicate for qualifying objects in the object graph. Thus you can fetch all the objects that match a query, but that is not the same as grouping those results. If you want to do aggregate operations, use Key-Value coding's collection operators. Under the hood, Core Data may convert these to sensible SQL, but that's exclusively an implementation detail.

In this case, you can get the set of unique packTitle values with

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

which will give you the distinct set of packTitle values in the myCards collection. If you want this for all cards in the Core Data stores, you will have to run a query for all cards, then apply this collection operation.

The alternative is to make a PackInformation entity, or some such which contains a title property. You can then have only 3 of these entities in the data store, referencing them from the appropriate pack entities. It's trivial to fetch all three (or whatever the final number is) and get their titles.

As others have said, if what you're trying to do is fundamentally reporting from a relational data set, you may better off going with straight SQLite. It all depends on how much other benefit you get from Core Data.

油焖大侠 2024-12-03 15:51:33

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

您不一定将“任意”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 可能会更好。

Assuming you're using CoreData... according to the Apple Documentation

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.

If you need to do complex queries like this, you might be better using SQLite.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文