SQLiteOpenHelper在Android中翻译SQLite查询

时间:2015-01-22 18:45:04

标签: android sqlite sqliteopenhelper

我有以下sqlite查询:

select product.title, supermarket.title,
       datetime(price.timestamp,'localtime'), price.price
   from price inner join product on price.productid = product._id
   inner join supermarket on price.supermarketid = supermarket._id
where price.productid = 1
group by price.productid, price.supermarketid, price.timestamp
order by price.productid, price.supermarketid, price.timestamp

我想在SQLiteOpenHelper的帮助下构建查询,所以我试着翻译它:

    SQLiteDatabase db = mDbHelper.getReadableDatabase();

    // Define a projection that specifies which columns to read from the database
    String[] projection = {
            DBContract.Product.COLUMN_NAME_TITLE,
            DBContract.Supermarket.COLUMN_NAME_TITLE,
            "datetime(DBContract.Price.COLUMN_NAME_TIMESTAMP, 'localtime')",
            DBContract.Price.COLUMN_NAME_PRICE
    };

    // Define 'where' part of query.
    String selection = DBContract.Price.COLUMN_NAME_PRODUCT_ID + " LIKE ?";

    // Specify arguments in placeholder order.
    String[] selectionArgs = { String.valueOf(productId) };

    // Define grouping by rows
    String groupBy = DBContract.Price.COLUMN_NAME_PRODUCT_ID
            .concat(DBContract.Price.COLUMN_NAME_SUPERMARKET_ID)
            .concat(DBContract.Price.COLUMN_NAME_TIMESTAMP);

    // Define order by clause
    String orderBy = DBContract.Price.COLUMN_NAME_PRODUCT_ID
            .concat(DBContract.Price.COLUMN_NAME_SUPERMARKET_ID)
            .concat(DBContract.Price.COLUMN_NAME_TIMESTAMP);

    Cursor cursor = db.query(
            DBContract.Product.TABLE_NAME,          // The table to query
            projection,                             // The columns to return
            selection,                              // The columns for the WHERE clause
            selectionArgs,                          // The values for the WHERE clause
            groupBy,                                // don't group the rows
            null,                                   // don't filter by row groups
            orderBy                                 // The sort order
    );

我的问题是:

  1. 我不知道在投影中指定下面是否正确:

    datetime(DBContract.Price.COLUMN_NAME_TIMESTAMP,' localtime')

  2. 我不知道如何使用这种语法指定内部联接。

  3. 我知道我可以通过直接构建查询并执行它来实现它,但我想以这种方式做,所以我怎么能摆脱它?

1 个答案:

答案 0 :(得分:1)

按查询分组需要在任何数据库上进行大量开销,因此请谨慎使用它们。分组用于获取小计和独特结果。假设时间戳对于productid和supermarketid是唯一的,它可能是因为我们不需要group by子句。 SQL like关键字也需要在任何数据库上花费大量开销,所以要谨慎使用它。

select product.title, supermarket.title,timestamp, 
   datetime(price.timestamp,'localtime') lt, price.price
from price inner join product on price.productid = product._id
inner join supermarket on price.supermarketid = supermarket._id
where price.productid = ?
order by price.productid, price.supermarketid, price.timestamp

请注意我如何选择时间戳和本地时间戳。这是因为大多数数据库都不允许您对查询中不存在的列进行排序,并且我们希望向用户显示本地时间戳。我给当地时间一个名字,所以我以后可以实际使用它。我给产品一个参数标记。稍后我们需要创建一个视图。

现在将简化的SQL更改为视图。

create view supermarketproductprice as 
select product.title, supermarket.title,timestamp, 
   datetime(price.timestamp,'localtime') lt, price.price
from price inner join product on price.productid = product._id
inner join supermarket on price.supermarketid = supermarket._id

我们需要一个价格表上的索引,该索引与查询的顺序完全匹配,以避免应用程序没有响应消息。

create index price_ix1 on price order by price.productid, price.supermarketid, price.timestamp

理想情况下,您可以在创建数据库时创建索引和视图。我有创建视图和创建索引语句作为常量

db.execSQL(VERSION_66_CREATE_TABLE);
            db.execSQL(VERSION_66_CREATE_INDEX);
            db.execSQL(VERSION_66_CREATE_VIEW);

现在它是从视图中选择的简单事项。

// Define a projection that specifies which columns to read from the database
String[] projection = {
        DBContract.Product.COLUMN_NAME_TITLE,
        DBContract.Supermarket.COLUMN_NAME_TITLE,
 // extra column for processing sort     price.COULUM_NAME_TIMESTAMP,"datetime(DBContract.Price.COLUMN_NAME_TIMESTAMP, 'localtime')",
        DBContract.Price.COLUMN_NAME_PRICE
};

// Define 'where' part of query.
String selection = DBContract.Price.COLUMN_NAME_PRODUCT_ID + "= ?";

// Specify arguments in placeholder order.
String[] selectionArgs = { String.valueOf(productId) };


// Define order by clause
String orderBy = DBContract.Price.COLUMN_NAME_PRODUCT_ID + ","
        + DBContract.Price.COLUMN_NAME_SUPERMARKET_ID + ","
        + DBContract.Price.COLUMN_NAME_TIMESTAMP;

Cursor cursor = db.query(
        MYVIEWNAME,          // The view to query
        projection,                             // The columns to return
        selection,                              // The columns for the WHERE clause
        selectionArgs,                          // The values for the WHERE clause