使用嵌套的复杂更新查询选择Android SQLite

时间:2012-06-06 11:08:50

标签: android sqlite select

android noob ... 我有两个表,country_tbl和city_tbl之间有一对多关系,我想将city_tbl.landmark_col中的值与GROUP_CONCAT()连接起来并插入所有landmark_col将单个String值作为country_tbl.all_landmarks列。 SQL似乎需要一个嵌套的SELECT来连接landmark_col值,然后再将它们传递给country_tbl ......类似于:

UPDATE country_tbl 
SET country_tbl.all_landmarks = (SELECT landmarks_col FROM 
                                    (SELECT country_id, group_concat(landmarks_col) 
                                            FROM city_tbl INNER JOIN country_tbl
                                            ON country_tbl.country_id = city_tbl.country_id
                                            GROUP BY country_tbl.country_id) 
                                    AS country_landmarks      
                                WHERE country_tbl.country_id = country_landmarks.country_id)
WHERE
EXISTS (
    SELECT *
    FROM country_landmarks
    WHERE country_tbl.country_id = country_landmarks.country_id
);

不确定是否支持嵌套的select语句,或者是否资源过于密集......必须有更好的方法,因为看起来使用rawQuery并不是最好的解决方案。不确定我是应该创建临时表,使用ContentProviders还是传递游标......?

1 个答案:

答案 0 :(得分:4)

我通过将长SQL查询分成两部分来回答这个问题。首先,我使用SQLiteQueryBuilder创建了一个子查询,然后使用rawQuery运行一个两列游标,其中包含landmark_names的location_id和group_concat值。然后,我可以循环浏览游标,使用该国家/地区所有地标名称的每个相应连接值更新国家/地区表。

下面的查询比上面的问题(我在发布之前简化)更复杂,只是因为我必须通过landmark_type_id加入地标列表与另一个landmark_type表,我的真正目标是连接更短的按国家/地区列出的landmark_type列表,而不是按国家/地区列出的所有landmark_names的长列表。无论如何,它有效。

    public void UpdateCountryLandmarks() throws SQLException {
    Cursor c = null;
    String subquery = SQLiteQueryBuilder.buildQueryString(
            // include distinct
            true,
            // FROM tables
            LANDMARK_TYPE_TABLE + "," + LANDMARKS_TABLE,
            // two columns (one of which is a group_concat()
            new String[] { LANDMARKS_TABLE + "." + LOCATION_ID + ", group_concat(" + LANDMARK_TYPE_TABLE + "." + LANDMARK_TYPE + ",\", \") AS " + LANDMARK_NAMES },
            // where
            LANDMARK_TYPE_TABLE + "." + LANDMARK_ID + "=" + LANDMARKS_TABLE + "." + LANDMARK_TYPE_ID,
            // group by
            LANDMARKS_TABLE + "." + LOCATION_ID, null, null, null);

    c = mDb.rawQuery(subquery, null);

    if (c.moveToFirst()) {
        do {
            String locationId = c.getString(c.getColumnIndex(LOCATION_ID));
            String landmarkNames = c.getString(c.getColumnIndex(LANDMARK_NAMES));
            ContentValues cv = new ContentValues();
            cv.put(LANDMARK_NAMES, landmarkNames);
            mDb.update(COUNTRY_TABLE, cv, LOCATION_ID + "=" + locationId, null);
        } while (c.moveToNext());
    }

    c.close();

    }