Multiple queries in SQLite for iOS
Need help here.
i managed to get the drinkName and categories working. http://dl.dropbox.com/u/418769/2.png
but i need to Distinct the categories and get a count value of the SQL database.
something like this http://dl.dropbox.com/u/418769/2.png and then this http://dl.dropbox.com/u/418769/3.png
how would i need to do to get it done ?
i need to run SELECT drinkID,drinkName from drinks,
SELECT DISTINCT categories from drinks &
count each categoies's row.. can it be done ?
this is my database looks like..http://dl.dropbox.com/u/418769/4.png
i'm following this http://mybankofknowledge.wordpress.com/2010/12/01/accessing-sqlite-from-iphone-table-view/
ok it kind of work.....i on this error
* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[NSMutableArray objectAtIndex:]: index 5 beyond bounds [0 .. 4]'
(void) getInitialDataToDisplay:(NSString *)dbPath { DrinkTabsAndNavAppDelegate *appDelegate = (DrinkTabsAndNavAppDelegate *)[[UIApplication sharedApplication] delegate];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sql = "SELECT drinkID, drinkName FROM drinks"; //const char *sql = "SELECT drinkName, categories FROM drinks"; sqlite3_stmt *selectstmt; if (sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) { while(sqlite3_step(selectstmt) == SQLITE_ROW) { NSInteger primaryKey = sqlite3_column_int(selectstmt, 0); 开发者_运维知识库 Drink *drinkObj = [[Drink alloc] initWithPrimaryKey:primaryKey]; drinkObj.drinkName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt,1)]; //drinkObj.categories = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 6)]; drinkObj.isDirty = NO; [appDelegate.drinksArray addObject:drinkObj]; [drinkObj release]; } }
} else sqlite3_close(database); //close db to release all memory }
(void) getCategory:(NSString *)dbPath { DrinkTabsAndNavAppDelegate *appDelegate = (DrinkTabsAndNavAppDelegate *)[[UIApplication sharedApplication] delegate];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sql = "SELECT DISTINCT category FROM drinks"; //const char *sql = "SELECT drinkName, categories FROM drinks"; sqlite3_stmt *selectstmt; if (sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) { while(sqlite3_step(selectstmt) == SQLITE_ROW) { NSInteger primaryKey = sqlite3_column_int(selectstmt, 0); Drink *catObj = [[Drink alloc] initWithPrimaryKey:primaryKey]; catObj.category = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)]; //drinkObj.categories = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 6)]; NSLog(@"run here"); catObj.isDirty = NO; [appDelegate.categoryArray addObject:catObj]; [catObj release]; } }
} else sqlite3_close(database); //close db to release all memory }
If you want a count of the drinks in each category:
select category, count(drinkid) as DrinksInThisCategory
from drinks
group by category
But a properly normalized database would have a separate CATEGORIES table and you'd have a categoryid in your DRINKS table.
There are two ways i can come up with, one is querying your db: SELECT drinkID FROM drinks where categories='catX'
once per category, then count rows of each. I think this could be accomplished by using some SQLite code to return all the counts with a single query.
The other way is using you appDelegate.drinksArray
. First order your query by categories
, then you could use a predicate almost same as the one above and using FOR drink IN drinksArray
(pseudo code here...) to count how many drinks have each category.
Performance wise, i think the best way is using sql to query both, drinks and count of each category, may be in two different queries o best in one.
I would probably go with an approach that used an NSMutableDictionary
instead of and array as the main datastructure.
-(void) addDrink:(Drink) drink
{
//_drinks has been initialised earlier and is of type NSMutableDictionary
NSMutableArray categoryDrinks = [_drinks objectForKey:drink.categories];
if (categoryDrinks == nil)
{
categoryDrinks = [[[NSMutableArray alloc] init] autorelease];
[_drinks setObject:categoryDrinks forKey:drink.categories];
}
[categoryDrinks addObject:drink];
}
This mimics the structure that you show in your images, the number of items in each category can now be found by calling [[_drinks objectForKey:categoryName] count]
. Look at the apple documentation for NSMutableDictionary
and NSMutableArray
If you just want the numbers there is the SQL GROUP BY
expression you can get to the category counts doing something like this
SELECT CategoryColName, COUNT(CategoryColName) FROM TableName GROUP BY CategoryColName
This will give you pairs with the name of your category and the count
One small advice, in your Drinks
object you use the property categories
. I always try to keep the plurality of the name in sync with the type of data. This means I only use the plural for something if it is a collection of sorts. Otherwise I use the singular, this can be extended to SQL columns, while the column contains the categories of all the drinks. It is still only one category per drink. You did name the other columns using the singular.
精彩评论