Android SQLite grop_concat多列

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

我正在尝试在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 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