I’m trying to create a quiz app with a database with two tables one for topics and one for the questions. The topicsID is a Foreign key in my questions table. I want to retrieve 2 random questions from each topicID there is 7 topics, so far I have only tried retrieving one topic but Idk how to retrieve the rest in the same function.
fun getAllQuestions(): ArrayList {
val qList = ArrayList<MathQuestions>()
val db: SQLiteDatabase = this.readableDatabase
var sqlStatement = "SELECT * FROM $QuestionTableName WHERE $QTopicColumn_ID = '1' ORDER BY RAND() LIMIT 2"
val cursor: Cursor = db.rawQuery(sqlStatement, null)
if (cursor.moveToFirst())
do {
val id: Int = cursor.getInt(0)
val tId: Int = cursor.getInt(1)
val question: String = cursor.getString(2)
val option1: String = cursor.getString(3)
val option2: String = cursor.getString(4)
val option3: String = cursor.getString(5)
val optionR: String = cursor.getString(6)
val p = MathQuestions(id, tId, question, option1, option2, option3, optionR)
qList.add(p)
} while (cursor.moveToNext())
cursor.close()
db.close()
return qList
}
2
Answers
One way is a recursive CTE where it will loop through your topics and then can use each topic from the loop to perform your ORDER BY RAND() LIMIT 2 query in the union all.
CTE – Common Table Expressions
You could use UNION‘s to combine multiple SELECTS.
However, the ORDER BY and LIMIT follow the UNION’s (i.e. is for the SELECT overall) as per :-
so you would need the ORDER and LIMITs embedded in sub queries which provide values for an IN clause in the SELECT/UNION. The subqueries per SELECT/UNION selecting the rowid columns of the 2 random questions which drives the actual rows selected by the SELECT/UNION thus allowing the ORDER BY AND LIMIT per select.
The following does what I believe you want and additionally ORDERs the entire set by topic :-
Additional
The following is an adaptation of the above that will work for any number of topics (obviously 0 topics will result in 0 rows/questions). Adding and removing topics doesn’t require the code to be changed :-