首页 > 解决方案 > 如何在 GROUP BY 之前对 Core Data 记录进行排序?

问题描述

想象一下我有这个核心数据实体

@objc(SomeEntity)
class SomeEntity: NSManagedObject {
  @NSManaged var date: Date
  @NSManaged var timeZoneIdentifier: String
  @NSManaged var name: String
  @NSManaged var brand: String
}

我想获取所有具有不同namebrand字段的行,但是对于每一行,我想要最新date最新的行。timeZoneIdentifier date

以下是一些示例数据:

日期 时区标识符 姓名
2020-01-01 美国/洛杉矶 名称 1 品牌1
2020-01-02 美国/蒂华纳 名称 1 品牌1
2020-01-03 美国/丹佛 名称 1 品牌 2
2020-01-04 美国/凤凰 名称 2 品牌1

我本质上想获取如下所示的.dictionaryResultType结果:

最后日期 lastDateTimeZoneIdentifier 姓名
2020-01-02 美国/蒂华纳 名称 1 品牌1
2020-01-03 美国/丹佛 名称 1 品牌 2
2020-01-04 美国/凤凰 名称 2 品牌1

您可以使用此 SQL 查询执行以下操作:

SELECT * FROM (SELECT * FROM SomeEntity ORDER BY date DESC) as sub GROUP BY sub.name, sub.brand;

我可以通过最少的查询使用 Core Data 实现相同的目标吗?我在网上找不到任何示例或文档来尝试做这样的事情。

我可以写一个NSFetchRequest基本上执行这个的:

SELECT date, timeZoneIdentifier, name, brand FROM SomeEntity GROUP BY name, brand ORDER BY date;

但是那个命令在 GROUP BY 之后,而不是之前。

我也可以写一个NSFetchRequest基本上执行这个的:

SELECT max(date), name, brand FROM SomeEntity GROUP BY name, brand;

几乎只是因为我想要最新的日期,但我当然会丢失timeZoneIdentifier该行的来源。我把这个例子写成一个要点,你可以把它扔到一个 Swift 操场上。

谢谢!

标签: ioscore-data

解决方案


propertiesToFetch正如您可能已经发现的那样,除了分组依据的属性和聚合函数之外,您不能指定任何其他内容。因此,您不能包含timeZoneIdentifier.

但是,您可以包含NSExpression表示评估对象的 (请参阅 参考资料NSExpression.expressionForEvaluatedObject)。这将为您提供带有max(date)- 的对象的 objectID,然后您可以获取该对象以获取其他属性值。


推荐阅读