SQLiteOpenHelper 在 Android 中翻译 SQLite 查询

SQLiteOpenHelper translating SQLite query in Android

我有以下 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. 我不知道在投影中指定以下是否正确:

    日期时间(DBContract.Price.COLUMN_NAME_TIMESTAMP, 'localtime')

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

我知道我可以通过直接构建查询并执行它来做到这一点,但我想这样做,所以我怎么能摆脱它呢?

Group by 查询在任何数据库上都需要大量开销,因此请谨慎使用它们。分组依据用于获取小计和唯一结果。假设 timestamp 对于 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

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

现在将简化 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

我们需要一个与查询顺序完全匹配的价格 table 的索引,以避免应用不响应消息。

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);

现在,从视图中 select 看是一件简单的事情。

// 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