我有以下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
);
我的问题是:
我不知道在投影中指定下面是否正确:
datetime(DBContract.Price.COLUMN_NAME_TIMESTAMP,' localtime')
我不知道如何使用这种语法指定内部联接。
我知道我可以通过直接构建查询并执行它来实现它,但我想以这种方式做,所以我怎么能摆脱它?
答案 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