我可以通过偏移和限制的位置获得单行。但我有一系列职位,我希望从这些职位获得行。
有没有办法在没有for循环的情况下使用单个查询获取这些行?
注意:我不知道该ID。我的案件位置不是ids。
为什么我需要这个:
SELECT question_id FROM questions where question_bank_id in (1, 3) ORDER BY RANDOM() LIMIT 5
上面的查询从1和3返回5个随机值。但我需要5行,从1行和5行5.我可以通过循环实现这一点。但是我的桌子很大。
所以我找到了一种有效实现这一目标的替代方案。这就是为什么我想先生成随机整数然后从那些位置获取值。
答案 0 :(得分:2)
要获得单行,您可以使用如下查询:
SELECT ... FROM ... ORDER BY ... LIMIT 1 OFFSET ?;
要获取多行,请合并多个查询:
SELECT ... FROM ... ORDER BY ... LIMIT 1 OFFSET ?
UNION ALL
SELECT ... FROM ... ORDER BY ... LIMIT 1 OFFSET ?
UNION ALL
SELECT ... FROM ... ORDER BY ... LIMIT 1 OFFSET ?
...
您需要一个for循环来构造此查询,因此执行多个查询可能会更容易。
答案 1 :(得分:1)
注意:这个答案是根据原始问题引用的mySQL
我不知道它是否适合您作为单个查询,但它可能会尽可能接近您:
SET @row_num = 0;
SELECT
*
FROM
(
SELECT
@row_num := @row_num + 1 AS row_number,
t.id
FROM
your_table AS t
ORDER BY
t.id) AS q
WHERE
q.row_number IN (3, 5);
我认为您希望按位排序,而不是唯一ID键。上面的查询创建临时row_number,可用于选择任意数量的位置。
请注意,行选择取决于ORDER BY
中的字段 - 它不必是id(主键)。
答案 2 :(得分:1)
我没试过(见下文),但您可以使用 MergeCursor 。
这是为所需的银行创建一个游标数组,然后使用它们创建 MergeCursor ,然后使用它。
遵循: -
String sqlbank1 =
"SELECT question_id FROM questions WHERE question_bank_id = 1 ORDER BY random() LIMIT 5";
String sqlbank2 =
"SELECT question_id FROM questions WHERE question_bank_id = 3 ORDER BY random() LIMIT 5";
Cursor[] cursors = new Cursor[]{db.rawQuery(sqlbank1),db.rawQuery(sqlbank2)};
Cursor questions = new MergeCursor(cursors);
// or MergeCursor questions = new MergCursor(cursors);
请注意!没有经过测试,所以代码原则上是 。你也应该关闭游标(我还没有尝试过,所以不确定是否关闭数组中的游标会影响MergeCursor,可能最好这样做并在完成时关闭所有游标)。
调用活动 MainActivity.java : -
public class MainActivity extends AppCompatActivity {
DatabaseHelper dbhlpr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbhlpr = new DatabaseHelper(this);
dbhlpr.populateQuestions(500,6);
Cursor questions = dbhlpr.getRandomQuestionsForBanks(new int[]{1,3},5);
while (questions.moveToNext()) {
Log.d("QUESTIONS",
"ID=" + questions.getLong(questions.getColumnIndex(DatabaseHelper.QUESTION_ID_COL)) +
" BANK=" + questions.getInt(questions.getColumnIndex(DatabaseHelper.QUESTION_BANK_ID))+
" QUESTION=" + questions.getString(questions.getColumnIndex(DatabaseHelper.QUESTION_QUESTION))
);
}
questions.close();
}
}
数据库助手 Databasehelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "questionsdb";
public static final int DBVERSION = 1;
public static final String QUESTIONS_TBNAME = "questions";
public static final String QUESTION_ID_COL = "question_id";
public static final String QUESTION_BANK_ID = "question_bank_id";
public static final String QUESTION_QUESTION = "question_question";
SQLiteDatabase mDB;
static Random r;
DatabaseHelper(Context context) {
super(context, DBNAME,null,DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String questions_crtsql = "CREATE TABLE IF NOt EXISTS " + QUESTIONS_TBNAME +
"(" +
QUESTION_ID_COL + " INTEGER PRIMARY KEY," +
QUESTION_BANK_ID + " INTEGER, " +
QUESTION_QUESTION + " TEXT" +
")";
db.execSQL(questions_crtsql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void populateQuestions(int rowstoadd, int numberofbanks) {
final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random r = new Random(System.currentTimeMillis());
ContentValues cv = new ContentValues();
if (DatabaseUtils.queryNumEntries(mDB,QUESTIONS_TBNAME) < 1) {
mDB.beginTransaction();
for (int i = 0; i < rowstoadd; i++) {
int aix = r.nextInt(alphabet.length());
int bank = r.nextInt(numberofbanks) + 1;
cv.clear();
cv.put(QUESTION_BANK_ID,bank);
cv.put(QUESTION_QUESTION,alphabet.substring(aix,aix+1));
mDB.insert(QUESTIONS_TBNAME,null,cv);
}
mDB.setTransactionSuccessful();
mDB.endTransaction();
Log.d("POPULATE","Number of rows in table after populate is" + DatabaseUtils.queryNumEntries(mDB,QUESTIONS_TBNAME));
} else {
Log.d("POPULATE","Number of rows in table is" + DatabaseUtils.queryNumEntries(mDB,QUESTIONS_TBNAME));
}
}
public Cursor getRandomQuestionsPerBank(int bank, int numbertoget) {
return mDB.query(
QUESTIONS_TBNAME,
new String[]{QUESTION_ID_COL, QUESTION_QUESTION, QUESTION_BANK_ID},
QUESTION_BANK_ID + "=?",
new String[]{Integer.toString(bank)},
null, null," random()",
Integer.toString(numbertoget)
);
}
public Cursor getRandomQuestionsForBanks(int[] banklist, int numbertoget) {
Cursor[] cursors = new Cursor[banklist.length];
for (int i=0; i < banklist.length; i++) {
cursors[i] = getRandomQuestionsPerBank(banklist[i],numbertoget);
}
return new MergeCursor(cursors);
}
}
3次运行的示例输出为: -
12-27 07:19:22.747 2370-2370/? D/POPULATE: Number of rows in table after populate is500
12-27 07:19:22.748 2370-2370/? D/QUESTIONS: ID=414 BANK=1 QUESTION=I
12-27 07:19:22.748 2370-2370/? D/QUESTIONS: ID=215 BANK=1 QUESTION=P
12-27 07:19:22.748 2370-2370/? D/QUESTIONS: ID=336 BANK=1 QUESTION=L
12-27 07:19:22.748 2370-2370/? D/QUESTIONS: ID=243 BANK=1 QUESTION=M
12-27 07:19:22.748 2370-2370/? D/QUESTIONS: ID=226 BANK=1 QUESTION=H
12-27 07:19:22.748 2370-2370/? D/QUESTIONS: ID=376 BANK=3 QUESTION=Y
12-27 07:19:22.748 2370-2370/? D/QUESTIONS: ID=282 BANK=3 QUESTION=M
12-27 07:19:22.748 2370-2370/? D/QUESTIONS: ID=113 BANK=3 QUESTION=M
12-27 07:19:22.748 2370-2370/? D/QUESTIONS: ID=80 BANK=3 QUESTION=O
12-27 07:19:22.748 2370-2370/? D/QUESTIONS: ID=413 BANK=3 QUESTION=D
12-27 07:23:29.502 2561-2561/? D/POPULATE: Number of rows in table is500
12-27 07:23:29.503 2561-2561/? D/QUESTIONS: ID=226 BANK=1 QUESTION=H
12-27 07:23:29.503 2561-2561/? D/QUESTIONS: ID=414 BANK=1 QUESTION=I
12-27 07:23:29.503 2561-2561/? D/QUESTIONS: ID=124 BANK=1 QUESTION=A
12-27 07:23:29.503 2561-2561/? D/QUESTIONS: ID=128 BANK=1 QUESTION=I
12-27 07:23:29.503 2561-2561/? D/QUESTIONS: ID=379 BANK=1 QUESTION=U
12-27 07:23:29.503 2561-2561/? D/QUESTIONS: ID=282 BANK=3 QUESTION=M
12-27 07:23:29.504 2561-2561/? D/QUESTIONS: ID=275 BANK=3 QUESTION=Z
12-27 07:23:29.504 2561-2561/? D/QUESTIONS: ID=371 BANK=3 QUESTION=C
12-27 07:23:29.504 2561-2561/? D/QUESTIONS: ID=106 BANK=3 QUESTION=M
12-27 07:23:29.504 2561-2561/? D/QUESTIONS: ID=35 BANK=3 QUESTION=B
12-27 07:24:06.794 2621-2621/mjt.questionsmergecursor D/POPULATE: Number of rows in table is500
12-27 07:24:06.795 2621-2621/mjt.questionsmergecursor D/QUESTIONS: ID=292 BANK=1 QUESTION=B
12-27 07:24:06.795 2621-2621/mjt.questionsmergecursor D/QUESTIONS: ID=201 BANK=1 QUESTION=F
12-27 07:24:06.795 2621-2621/mjt.questionsmergecursor D/QUESTIONS: ID=384 BANK=1 QUESTION=I
12-27 07:24:06.795 2621-2621/mjt.questionsmergecursor D/QUESTIONS: ID=305 BANK=1 QUESTION=M
12-27 07:24:06.796 2621-2621/mjt.questionsmergecursor D/QUESTIONS: ID=50 BANK=1 QUESTION=S
12-27 07:24:06.796 2621-2621/mjt.questionsmergecursor D/QUESTIONS: ID=295 BANK=3 QUESTION=U
12-27 07:24:06.796 2621-2621/mjt.questionsmergecursor D/QUESTIONS: ID=66 BANK=3 QUESTION=Z
12-27 07:24:06.796 2621-2621/mjt.questionsmergecursor D/QUESTIONS: ID=290 BANK=3 QUESTION=F
12-27 07:24:06.796 2621-2621/mjt.questionsmergecursor D/QUESTIONS: ID=91 BANK=3 QUESTION=O
12-27 07:24:06.796 2621-2621/mjt.questionsmergecursor D/QUESTIONS: ID=433 BANK=3 QUESTION=S
请注意!我测试了关闭数组游标,你不能得到java.lang.IllegalStateException: attempt to re-open an already-closed object
。所以代码应该有助于关闭数组游标。
答案 3 :(得分:-2)
您可以使用IN
。与SELECT * FROM table_name WHERE ID IN (1,2,3,4,5);
答案 4 :(得分:-2)
方式1:
您可以使用以下查询来实现此目的:
Select * from your_table_name where rowid in (1,5,6,10,15);
此处,在方括号(1,5,6,10,15)
中,您将从您的位置数组中传递位置。
方式2 :(适用于少量数据)
如果方式1 不符合您的要求,请将此表中的所有记录提取到一个列表中,并从此列表中获取所需位置的项目。
答案 5 :(得分:-2)
使用这样的SQL语句:
SELECT column_name(s)FROM table_name WHERE位置IN(1,2,...);