How do I use an SQL GROUP BY and SUM functions in a IOS CORE-DATA request in SWIFT?

我怕爱的太早我们不能终老 提交于 2019-12-17 19:37:00

问题


I have a table (Transactions) which holds records containing the Account_name and an Amount for the transaction. I would like to calculate the total for all transactions per account which start with 'Private' and for which the transaction amount is > 1000. I would like to get the accounts sorted by name, in a descending order.

So the SQL request would be something like this :

    SELECT Account_name, SUM(Amount) 
    FROM Transactions
    WHERE Account_name like 'Private%'
    and Amount > 1000
    GROUP BY Account_name
    ORDER BY Account_name DESC

How would I do this using Core-DATA in Swift.

Thanks


回答1:


Bear in mind that CoreData is not a relational database, so you should think of entities not "tables", and objects not "records". Note also that by convention, attribute names should not begin with Uppercase letters. That said, it is possible to construct a fetch to achieve what you want. The key steps are:

  1. create a fetch request
  2. specify an NSPredicate to filter according to your chosen criteria
  3. set the resultType to .DictionaryResultType (required for "Group By")
  4. set the properties to be included in the fetch (to get the sum(), this involves creating an NSExpression and associated NSExpressionDescription).
  5. set the properties to group by
  6. Create an NSSortDescriptor to order by name, descending
  7. Execute the fetch

See the following code:

let fetch = NSFetchRequest(entityName: "Transaction")
let predicate = NSPredicate(format: "Account_name like %@ AND Amount > %@", "Private*",NSNumber(double: 1000.0))
fetch.predicate = predicate
fetch.resultType = .DictionaryResultType
let sumExpression = NSExpression(format: "sum:(Amount)")
let sumED = NSExpressionDescription()
sumED.expression = sumExpression
sumED.name = "sumOfAmount"
sumED.expressionResultType = .DoubleAttributeType
fetch.propertiesToFetch = ["Account_name", sumED]
fetch.propertiesToGroupBy = ["Account_name"]
let sort = NSSortDescriptor(key: "Account_name", ascending: false)
fetch.sortDescriptors = [sort]
let results = managedObjectContext?.executeFetchRequest(fetch, error: nil) as NSArray?

The result will be an array of dictionaries, with keys "Account_name" and "sumOfAmount".

EDIT To extract the value for a particular Account_name, use another predicate:

    let newPredicate = NSPredicate(format: "Account_name like %@", "toto")!
    if let resultsArray = results { // to unwrap the optional
        let filteredResults = resultsArray.filteredArrayUsingPredicate(newPredicate)
        let sumOfAmount = (filteredResults[0] as NSDictionary)["sumOfAmount"] as Double
    }

I've ignored the fact that the previous example filtered Account_name to those beginning "Private", and assumed you will have one (and only one) account with name "toto" (hence filteredResults[0]); your production code should check.



来源:https://stackoverflow.com/questions/28010110/how-do-i-use-an-sql-group-by-and-sum-functions-in-a-ios-core-data-request-in-swi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!