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还是传递游标......?
答案 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();
}