【发布时间】:2020-12-18 15:23:24
【问题描述】:
想象一下我有这个核心数据实体
@objc(SomeEntity)
class SomeEntity: NSManagedObject {
@NSManaged var date: Date
@NSManaged var timeZoneIdentifier: String
@NSManaged var name: String
@NSManaged var brand: String
}
我想获取具有不同 name 和 brand 字段的所有行,但对于每一行,我想要 最新的 date 和 timeZoneIdentifier 的最新 date 行。
以下是一些示例数据:
| date | timeZoneIdentifier | name | brand |
|---|---|---|---|
| 2020-01-01 | America/Los_Angeles | Name 1 | Brand 1 |
| 2020-01-02 | America/Tiajuana | Name 1 | Brand 1 |
| 2020-01-03 | America/Denver | Name 1 | Brand 2 |
| 2020-01-04 | America/Phoenix | Name 2 | Brand 1 |
我基本上想获取如下所示的.dictionaryResultType 结果:
| lastDate | lastDateTimeZoneIdentifier | name | brand |
|---|---|---|---|
| 2020-01-02 | America/Tiajuana | Name 1 | Brand 1 |
| 2020-01-03 | America/Denver | Name 1 | Brand 2 |
| 2020-01-04 | America/Phoenix | Name 2 | Brand 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。 I have written up this example as a gist 你可以扔进 Swift 游乐场。
谢谢!
【问题讨论】:
-
您可能已经发现,除了您分组的属性和聚合函数之外,您不能指定任何 propertiesToFetch。因此,您不能包含 timeZoneIdentifier。但是,您可以包含一个表示评估对象的 NSExpression(请参阅 NSExpression.expressionForEvaluatedObject)。这将为您提供具有 max(date) 的对象的 objectID - 然后您可以获取该对象以获取其他属性值。
-
就是这样@pbasdf!两个查询而不是 O(n)。我更新了要点:gist.github.com/jmacdonagh/714b52a0f545a65bad26b233cb2315b9。随意提交一个实际的答案,所以我可以给你信用!谢谢!