Android SQLite grop_concat多列
我正在尝试在android中运行以下查询。当我尝试检索列“d”的值时,它返回null。但我可以得到一个*值:( 查询:Android SQLite grop_concat多列,android,sqlite,group-concat,Android,Sqlite,Group Concat,我正在尝试在android中运行以下查询。当我尝试检索列“d”的值时,它返回null。但我可以得到一个*值:( 查询: select a.*,group_concat(b._id || ', ' || b.product_id || ', ' || b.no_of_units || ', ' || b.unit_price || ', ' || b.discount || ', ' || b.discount, '; ') as d from transactions a join t
select a.*,group_concat(b._id || ', ' || b.product_id || ', ' || b.no_of_units || ', ' || b.unit_price || ', ' || b.discount || ', ' || b.discount, '; ') as d
from transactions a join transactions b on a._id=b.local_ref_txn_id
group by a.id
代码:
由于以下原因,您的上述代码将无法工作/无法按预期工作:- 首先,您试图访问一个名为Cursor的游标,而您生成的游标名为mCursor 相反,您似乎正在访问以前创建/提取的游标,假定该游标中存在列d,则该游标很可能具有列d的错误数据 因此,代码应为(仅用于纠正上述问题):- 但是,上述操作将失败,出现一个
android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
这是因为没有尝试移动到光标内的行,因此光标位于“第一行之前”位置(即位置-1)
要更正上述问题,您需要移动到有效行(如果有)。假设您将提取任意数量的行,则可以使用以下方法处理每一行:-
private void SO51603383() {
Cursor mCursor;
SO51603383DBHelper MyDbHelper = new SO51603383DBHelper(this);
mCursor = MyDbHelper.getReadableDatabase().rawQuery("select group_concat(b._id || ', ' || b.product_id || ', ' || b.no_of_units || ', ' || b.unit_price || ', ' || b.discount || ', ' || b.discount, '; ') as d,a.* \n" +
"from transactions a left join transactions b on a._id=b.local_ref_txn_id " +
"group by a._id", null);
while (mCursor.moveToNext()) {
String details = mCursor.getString(mCursor.getColumnIndex("d"));
}
}
当/如果您运行时,当您使用LEFT JOIN时,您可能会得到空值,如下所示:-
如果联接运算符是“左联接”或“左外联接”,则在
已应用ON或USING筛选子句,将添加一行
添加到原始左侧输入中每行的输出中
在复合数据集中根本不对应任何行的数据集
(如果有)。添加的行在将
通常包含从右侧输入数据集中复制的值
因此,您可能希望改用JOIN
例
将以下内容用作数据库帮助器:-
public class SO51603383DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "SO51603383.db";
public static final int DBVERSION = 1;
public static final String TB_TRANSACTIONS = "transactions";
public static final String COL_TRANSACTIONS_ID = BaseColumns._ID;
public static final String COl_TRANSACTIONS_NAME = "name";
public static final String COL_TRANSACTIONS_PRODUCTID = "product_id";
public static final String COL_TRANSACTIONS_NO_OF_UNITS = "no_of_units";
public static final String COL_TRANSACTIONS_UNIT_PRICE = "unit_price";
public static final String COL_TRANSACTIONS_DISCOUNT = "discount";
public static final String COl_TRANSACTIONS_LOCAL_REF_TXN = "local_ref_txn_id";
SQLiteDatabase mDB;
public SO51603383DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String crtsql = "CREATE TABLE IF NOT EXISTS " + TB_TRANSACTIONS + "(" +
COL_TRANSACTIONS_ID + " INTEGER PRIMARY KEY," +
COl_TRANSACTIONS_NAME + " TEXT," +
COL_TRANSACTIONS_PRODUCTID + " INTEGER, " +
COL_TRANSACTIONS_NO_OF_UNITS + " INTEGER, " +
COL_TRANSACTIONS_UNIT_PRICE + " INTEGER, " +
COL_TRANSACTIONS_DISCOUNT + " INTEGER, " +
COl_TRANSACTIONS_LOCAL_REF_TXN + " INTEGER" +
")";
db.execSQL(crtsql);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public long add(String name, long productid, int units, int price, int discount, long localref) {
ContentValues cv = new ContentValues();
cv.put(COl_TRANSACTIONS_NAME,name);
cv.put(COL_TRANSACTIONS_PRODUCTID,productid);
cv.put(COL_TRANSACTIONS_NO_OF_UNITS,units);
cv.put(COL_TRANSACTIONS_UNIT_PRICE,price);
cv.put(COL_TRANSACTIONS_DISCOUNT,discount);
cv.put(COl_TRANSACTIONS_LOCAL_REF_TXN,localref);
return mDB.insert(TB_TRANSACTIONS,null,cv);
}
}
使用加载2行(请参见上面的添加方法):-
然后运行:-
mCursor = MyDbHelper.getReadableDatabase().rawQuery(
"select group_concat(b._id || ', ' || b.product_id || ', ' || b.no_of_units || ', ' || b.unit_price || ', ' || b.discount || ', ' || b.discount, '; ') " +
"as d,a.* \n" +
"from transactions a left join transactions b on a._id=b.local_ref_txn_id " +
"group by a._id", null);
while (mCursor.moveToNext()) {
String details = mCursor.getString(mCursor.getColumnIndex("d"));
Log.d("DETAILS","Column D from query is :- " + details);
}
导致日志的以下输出(1行有数据,1行有空):-
更改为使用:-
mCursor = MyDbHelper.getReadableDatabase().rawQuery(
"select group_concat(b._id || ', ' || b.product_id || ', ' || b.no_of_units || ', ' || b.unit_price || ', ' || b.discount || ', ' || b.discount, '; ') " +
"as d,a.* \n" +
//"from transactions a left join transactions b on a._id=b.local_ref_txn_id " +
"from transactions a join transactions b on a._id=b.local_ref_txn_id " +
"group by a._id", null);
while (mCursor.moveToNext()) {
String details = mCursor.getString(mCursor.getColumnIndex("d"));
Log.d("DETAILS","Column D from query is :- " + details);
}
结果(清除数据库后):-
使用第一个代码(左连接)并运行第二次,从而添加另外两行(除_id值外的重复行),结果是:-
07-31 05:59:04.095 2440-2440/? D/DETAILS: Column D from query is :- 2, 1, 20, 24, 5, 5; 4, 1, 20, 24, 5, 5
Column D from query is :- null
Column D from query is :- null
Column D from query is :- null
07-31 06:05:00.610 2565-2565/soanswers.soanswers D/DETAILS: Column D from query is :- 2, 1, 20, 24, 5, 5; 4, 1, 20, 24, 5, 5
使用第二个(just JOIN)代码并运行两次,结果是:-
07-31 05:59:04.095 2440-2440/? D/DETAILS: Column D from query is :- 2, 1, 20, 24, 5, 5; 4, 1, 20, 24, 5, 5
Column D from query is :- null
Column D from query is :- null
Column D from query is :- null
07-31 06:05:00.610 2565-2565/soanswers.soanswers D/DETAILS: Column D from query is :- 2, 1, 20, 24, 5, 5; 4, 1, 20, 24, 5, 5
谢谢您的回复。我忘了提到检索是在游标适配器中完成的,因此游标名称和值是在SQLite2009 Pro中提供的。@Mashfiqurrahmananida然后最后一节重新左连接是问题所在。我想是的,但我知道该值存在。因为它来自mysql db与sqlite db同步。该值可能是问题所在很有可能会提取许多值和行。您是否尝试过将左连接更改为连接?如果没有,我建议编辑您的问题以包含SQL以创建和填充表,然后可以分析/解释实际结果。可能是我发现了问题,一旦值同步,本地\u ref\u txn\u id和\u id虽然有值,但不知何故不匹配。尽管奇怪
07-31 05:56:38.872 2380-2380/soanswers.soanswers D/DETAILS: Column D from query is :- 2, 1, 20, 24, 5, 5
07-31 05:59:04.095 2440-2440/? D/DETAILS: Column D from query is :- 2, 1, 20, 24, 5, 5; 4, 1, 20, 24, 5, 5
Column D from query is :- null
Column D from query is :- null
Column D from query is :- null
07-31 06:05:00.610 2565-2565/soanswers.soanswers D/DETAILS: Column D from query is :- 2, 1, 20, 24, 5, 5; 4, 1, 20, 24, 5, 5