SQLite for iOS中的多个查询

时间:2011-07-28 13:01:12

标签: iphone ios xcode sqlite

需要帮助。

我设法让drinkName和类别工作。 http://dl.dropbox.com/u/418769/2.png

但我需要区分类别并获取SQL数据库的计数值。

类似于此http://dl.dropbox.com/u/418769/2.png,然后是此http://dl.dropbox.com/u/418769/3.png

我需要怎么做才能完成它?

我需要从饮料中运行SELECT drinkID,drinkName,

从饮品中选择DISTINCT类别&

计算每个categoies的行......可以吗?

这是我的数据库看起来像..http://dl.dropbox.com/u/418769/4.png

我正在关注此http://mybankofknowledge.wordpress.com/2010/12/01/accessing-sqlite-from-iphone-table-view/

确定它有点工作.....我在这个错误

*由于未捕获的异常'NSRangeException'而终止应用程序,原因:'* - [NSMutableArray objectAtIndex:]:索引5超出边界[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(数据库); //关闭db以释放所有内存 }

  • (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(数据库); //关闭db以释放所有内存 }

3 个答案:

答案 0 :(得分:2)

如果您想要计算每个类别的饮品数量:

           select category, count(drinkid) as DrinksInThisCategory
           from drinks
           group by category

但正确规范化的数据库会有一个单独的CATEGORIES表,并且您的DRINKS表中有一个categoryid。

答案 1 :(得分:1)

我有两种方法可以提出,一种是每个类别查询一次db:SELECT drinkID FROM drinks where categories='catX',然后计算每行的行数。我认为这可以通过使用一些SQLite代码通过单个查询返回所有计数来实现。

另一种方式是使用你appDelegate.drinksArray。首先按categories对您的查询进行排序,然后您可以使用与上述谓词几乎相同的谓词,并使用FOR drink IN drinksArray(此处为伪代码...)来计算每个类别的饮品数量。

性能方面,我认为最好的方法是使用sql来查询每个类别的饮料和计数,可以在两个不同的查询中最好合一。

答案 2 :(得分:1)

我可能会采用一种方法,使用NSMutableDictionary代替和数组作为主数据结构。

-(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];
}

这模仿了您在图片中显示的结构,现在可以通过调用[[_drinks objectForKey:categoryName] count]找到每个类别中的项目数。查看NSMutableDictionaryNSMutableArray

的苹果文档

如果您只想要数字,那么就有SQL GROUP BY表达式,您可以按照这样的方式进行类别计数

SELECT CategoryColName,COUNT(CategoryColName)FROM TableName GROUP BY CategoryColName

这将为您提供类别名称和计数

您使用属性Drinks的{​​{1}}对象中的一条小建议。我总是试图使多个名称与数据类型保持同步。这意味着如果它是各种各样的集合,我只使用复数形式。否则我使用单数,这可以扩展到SQL列,而列包含所有饮料的类别。每种饮料仍然只有一类。您确实使用单数命名其他列。