У меня есть проект Android, у которого есть база данных с двумя таблицами: tbl_question
и tbl_alternative
.
Чтобы заполнить представления вопросами и альтернативами, я использую курсоры. Нет никаких проблем с получением данных, которые мне нужны, пока я не попытаюсь присоединиться к двум таблицам.
Tbl_question ------------- _id question categoryid
Tbl_alternative --------------- _id questionid categoryid alternative
Мне нужно что-то вроде следующего:
SELECT tbl_question.question, tbl_alternative.alternative where
categoryid=tbl_alternative.categoryid AND tbl_question._id =
tbl_alternative.questionid.`
Это моя попытка:
public Cursor getAlternative(long categoryid) {
String[] columns = new String[] { KEY_Q_ID, KEY_IMAGE, KEY_QUESTION, KEY_ALT, KEY_QID};
String whereClause = KEY_CATEGORYID + "=" + categoryid +" AND "+ KEY_Q_ID +"="+ KEY_QID;
Cursor cursor = mDb.query(true, DBTABLE_QUESTION + " INNER JOIN "+ DBTABLE_ALTERNATIVE, columns, whereClause, null, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
Я нахожу этот способ, чтобы сформировать запросы сложнее обычного SQL, но получил совет использовать этот способ, поскольку он менее подвержен ошибкам.
Как мне присоединиться к двум таблицам SQLite в моем приложении?
Вам нужен rawQuery.
Пример:
private final String MY_QUERY = "SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.other_id WHERE b.property_id=?";
db.rawQuery(MY_QUERY, new String[]{String.valueOf(propertyId)});
Использовать? вместо привязки значений к необработанному sql-запросу.
Use your downvotes whenever you encounter an egregiously sloppy, no-effort-expended post, or an answer that is clearly and perhaps dangerously incorrect.
,
Альтернативный способ - создать представление, которое затем запрашивается точно так же, как таблица. Во многих менеджерах баз данных использование представления может привести к повышению производительности.
CREATE VIEW xyz SELECT q.question, a.alternative
FROM tbl_question AS q, tbl_alternative AS a
WHERE q.categoryid = a.categoryid
AND q._id = a.questionid;
Это из памяти, поэтому могут возникать некоторые синтаксические проблемы. http://www.sqlite.org/lang_createview.html
Я упоминаю этот подход, потому что тогда вы можете использовать SQLiteQueryBuilder с представлением, поскольку вы подразумевали, что это было предпочтительным.
rawQuery()
является правильным ответом.
В дополнение к ответу @pawelzieba, который определенно правильный, присоединиться к двум таблицам, в то время как вы можете использовать INNER JOIN
, как этот
SELECT * FROM expense INNER JOIN refuel
ON exp_id = expense_id
WHERE refuel_id = 1
через сырой запрос вроде этого -
String rawQuery = "SELECT * FROM " + RefuelTable.TABLE_NAME + " INNER JOIN " + ExpenseTable.TABLE_NAME
+ " ON " + RefuelTable.EXP_ID + " = " + ExpenseTable.ID
+ " WHERE " + RefuelTable.ID + " = " + id;
Cursor c = db.rawQuery(
rawQuery,
null
);
из-за обратной поддержки SQLite примитивного способа запроса, мы превращаем эту команду в это -
SELECT *
FROM expense, refuel
WHERE exp_id = expense_id AND refuel_id = 1
и, следовательно, иметь возможность использовать расширенный метод поддержки SQLiteDatabase.query()
Cursor c = db.query(
RefuelTable.TABLE_NAME + " , " + ExpenseTable.TABLE_NAME,
Utils.concat(RefuelTable.PROJECTION, ExpenseTable.PROJECTION),
RefuelTable.EXP_ID + " = " + ExpenseTable.ID + " AND " + RefuelTable.ID + " = " + id,
null,
null,
null,
null
);
Для подробного сообщения в блоге проверьте это http://blog.championswimmer.in/2015/12/doing-a-table-join-in-android-without-using-rawquery
"Неоднозначный столбец" обычно означает, что одно и то же имя столбца отображается как минимум в двух таблицах; механизм базы данных не может определить, какой из них вы хотите. Используйте полные имена таблиц или псевдонимы таблиц, чтобы устранить двусмысленность.
Вот пример, который у меня был в моем редакторе. Это от чужой проблемы, но должно иметь смысл в любом случае.
select P.*
from product_has_image P
inner join highest_priority_images H
on (H.id_product = P.id_product and H.priority = p.priority)