问题
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:
- create a fetch request
- specify an
NSPredicate
to filter according to your chosen criteria - set the
resultType
to.DictionaryResultType
(required for "Group By") - set the properties to be included in the fetch (to get the sum(), this involves creating an
NSExpression
and associatedNSExpressionDescription
). - set the properties to group by
- Create an
NSSortDescriptor
to order by name, descending - 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