【CoreData】
指定したカラムの最大値(max値)・最小値(min値)を取得する方法

@max・@minを使用しよう

投稿日 2024/09/18 更新日 2024/09/18


こんにちは。IT業界歴5年目の「元木皇天」です。

今回はiOS向けDBのCoreDataで、指定したカラムの最大値(max値)を取得する方法について解説いたします。

やりたいこと

CoreDataで指定したカラムの最大値(max値)を取得する

idカラムから最大値を取得する

参考文献

tomato-develop - 【SwiftUI】CoreData のデータ取得メソッドの実装【NSPredicateによる条件指定も解説】


環境

・OS:MacOS Sonoma 14.6.1
・Swift:Ver 5.3
・Xcode:Ver 15.2

はじめに

他のCoreData関連記事では以下のような取得方法について記載されていることが多い。 これは主にView内で定義してデータを取得する方法であり、今回の記事では関数内で最大値・最小値のデータを取得する方法について解説していますので、あらかじめご了承ください。

//以下のような取得方法についての解説ではない
@FetchRequest(
    entity: SAMPLE.entity(),
    sortDescriptors: [NSSortDescriptor(keyPath: \SAMPLE.id, ascending: false)],
    predicate: nil
) var sampleList: FetchedResults<SAMPLE>

また、今回例として使用するテーブル(エンティティ)は以下とする。

エンティティ名:SAMPLE
id(Integer32)name(String)
1sato
95tanaka
32yamada

max値の取得方法

以下は先ほど定義した「SAMPLE」エンティティの「id」から最大値を取得する関数です。

import CoreData

struct SelectMaxId{
    func exe() -> Int32{
        //DB操作のコンテキストを生成
        let persistenceController = PersistenceController.shared
        let context = persistenceController.container.viewContext

        //実行内容を生成する
        //エンティティの指定(SQLのfromに相当)
        let request = NSFetchRequest<SAMPLE>(entityName: "SAMPLE")
        //取得条件の指定(SQLのwhereに相当)
        request.predicate = NSPredicate(format: "id == @max.id")

        do {
            //データの取得
            let result: [SAMPLE] = try context.fetch(request)
            //取得結果の1件目のidを返す
            return result[0].id
        } catch {
            return 0
        }
    }
}

ポイントとなるのは、「NSPredicate」です(以下該当箇所抜粋)。

let request = NSFetchRequest<SAMPLE>(entityName: "SAMPLE")
request.predicate = NSPredicate(format: "id == @max.id")

NSPredicateを使用することで、取得するデータの条件を指定することができます。

ここではidの値がエンティティのidの最大値と同じものを取得するような条件となっています。

これによって以下のデータが取得されます。

エンティティ名:SAMPLE
id(Integer32)name(String)
95tanaka

あとは、最後に取得したデータのidの値を返却してあげればOKです。

-補足-

他の記事やChatGPTなどに質問した結果を見ると、よく「NSExpression」を使用する方法が出てきます。

おそらくその方法でもできるのでしょうが、個人的には今回紹介した方法の方が簡潔に記載できて、コード的にも読みやすいと感じています。

また、個人的な予想ですが「NSExpression」を使用する方法は、Swift以前の「Objective-C」が使われていた時代に使用されていた記述方法なのではないかと思っております(エビデンスは特にないです...。)。

min値の取得方法

最小値を取得するには、先ほど紹介した最大値を取得するコードのうち以下の赤線部分を変更することで実現することができます。

let request = NSFetchRequest<SAMPLE>(entityName: "SAMPLE")
request.predicate = NSPredicate(format: "id == @min.id")

以下のデータが取得できます。

エンティティ名:SAMPLE
id(Integer32)name(String)
1sato

まとめ

CoreDataで最大値・最小値を取得するには「NSPredicate」を使用し、条件として@maxまたは@min を使用して一致するデータを取得する。

参考文献・おすすめ文献

tomato-develop - 【SwiftUI】CoreData のデータ取得メソッドの実装【NSPredicateによる条件指定も解説】