У вас должно быть что-то не так в другом месте, код прекрасно работает на Android, согласно ( sql, скопированный в logIt метод ): -
public class DBHelper001 extends SQLiteOpenHelper {
public static final String DBNAME = "db";
public static final int DBVERSION =1;
public static final String TABLE_PLAYER = "player_card";
public static final String COL_PLAYERCARD_CARD = "card";
public static final String COL_PLAYERCARD_EMAIL = "email";
public static final String COL_PLAYERCARD_REGION = "region";
public static final String COL_PLAYERCARD_Q = "quantidade";
SQLiteDatabase mDB;
public DBHelper001(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase(); //<<<<<<<<<< when helper is instantiated will force on Create and thus the logIt method to run.
}
@Override
public void onCreate(SQLiteDatabase db) {
mDB = db;
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_PLAYER + "(" +
COL_PLAYERCARD_CARD + " TEXT, " +
COL_PLAYERCARD_EMAIL + " TEXT, " +
COL_PLAYERCARD_REGION + " TEXT," +
COL_PLAYERCARD_Q + " INTEGER," +
"PRIMARY KEY (" +
COL_PLAYERCARD_EMAIL + "," +
COL_PLAYERCARD_REGION + "," +
COL_PLAYERCARD_CARD + ")" +
")"
);
//<<<<<<<<<< Add some test data
insertPlayerCard("card1","a@x.id","EU",1);
insertPlayerCard("card2","a@x.id","EU",1);
insertPlayerCard("card1","a@x.id","US",1);
//<<<<<<<<<< INVOKE THE LOGIT METHOD >>>>>>>>>>
logIt();
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
public long insertPlayerCard(String card, String email, String region, long quantitade) {
ContentValues cv = new ContentValues();
cv.put(COL_PLAYERCARD_CARD,card);
cv.put(COL_PLAYERCARD_EMAIL,email);
cv.put(COL_PLAYERCARD_REGION,region);
cv.put(COL_PLAYERCARD_Q,quantitade);
return mDB.insert(TABLE_PLAYER,null,cv);
}
//<<<<<<<<<< THE LOGIT METHOD RUNS QUERY AS COPIED AND REPORTS ROWS EXTRACTED >>>>>>>>>>
public void logIt() {
String sql = "SELECT * FROM player_card " +
"WHERE email " +
"In (SELECT email FROM player_card As Tmp " +
" GROUP BY email, card " +
" HAVING COUNT(*) > 1 AND card = player_card.card) " +
" ORDER BY email;";
Cursor csr = mDB.rawQuery(sql,null);
Log.d("RESULT","Number of rows extracted = " + String.valueOf(csr.getCount()));
csr.close();
}
}
Простое создание экземпляра и экземпляр (если база данных не существует) запускает метод logIt
, который возвращает: -
12-08 05:31:50.247 2049-2049/? D/RESULT: Number of rows extracted = 2
Дополнительное повторное редактирование в оригиналевопрос
Дело не в том, что вы не можете сделать это на Android, вы можете, НО это требует времени.
Короче говоря, база данных, приведенная выше, была загружена 20997 строками, а запрос применен 3 раза: -
- 1-й для компенсации проблем с кэшированием / первым запуском
- 2-й - 1-й тестовый запуск.
- 3-й после создания индекса для столбца карты.
Каждый запуск работал, НО каждый занимал 20 минут (на эмулируемом устройстве, которое, я считаю, может быть быстрее, чем некоторые реальные устройства).
- Обратите внимание, что все выполняются в потоке, чтобыизбегайте ANR (Android не отвечает, возможно, это ваша проблема)
результаты loged as: -
12-09 02:02:33.325 3702-3715/so53646027.so53646027 D/THREADREPORT: Started at (getting row count)2018-12-09 00:57:35.609+0000
Number of Rows in player_card is 20997 at 2018-12-09 00:57:35.633+0000
Finished Run to ignore chacheing effects at 2018-12-09 01:19:04.769+0000
Finished Test Run without Index (started creating index on card column) at 2018-12-09 01:40:54.147+0000
Finished Creating Index at; Starting Test Run with Index at 2018-12-09 01:40:54.223+0000
Finished 2nd Test Run (now dropping index) at 2018-12-09 02:02:33.321+0000
Finished at 2018-12-09 02:02:33.328+0000
Затем я скопировал базу данных и выполнил тот же самый запрос (один раз) в Navicat (здесь не самый медленный ПК в мире), для выполнения которого потребовалась доля менее 6 минут.
Из других тестов ясно, что card = player_card.card
является основной проблемой.Перемещение его в предложение WHERE значительно сокращает время запроса до того времени, которое я считаю приемлемым / приемлемым, например: -
12-09 06:09:54.501 4845-4858/so53646027.so53646027 D/THREADREPORT: Started at (getting row count)2018-12-09 06:09:50.474+0000
Number of Rows in player_card is 20997 at 2018-12-09 06:09:50.477+0000
Finished Run to ignore chacheing effects at 2018-12-09 06:09:51.858+0000
Finished Test Run without Index (started creating index on card column) at 2018-12-09 06:09:52.969+0000
Finished Creating Index at; Starting Test Run with Index at 2018-12-09 06:09:53.048+0000
Finished 2nd Test Run (now dropping index) at 2018-12-09 06:09:54.499+0000
Finished at 2018-12-09 06:09:54.505+0000
Примерно 1,5 секунды, с теми же результатами, что и при полной регистрации: -
12-09 06:09:51.853 4845-4858/so53646027.so53646027 D/RESULT: Number of rows extracted = 7368
12-09 06:09:51.853 4845-4858/so53646027.so53646027 D/THREADREPORT: Finished Run to ignore cacheing at 2018-12-09 06:09:51.857+0000
12-09 06:09:52.965 4845-4858/so53646027.so53646027 D/RESULT: Number of rows extracted = 7368
12-09 06:09:52.965 4845-4858/so53646027.so53646027 D/THREADREPORT: Finished 1st Test RUN (not indexed, now building Index) at 2018-12-09 06:09:52.969+0000
12-09 06:09:53.045 4845-4858/so53646027.so53646027 D/THREADREPORT: Index created (starting 2nd Test Run) at 2018-12-09 06:09:53.048+0000
12-09 06:09:54.493 4845-4858/so53646027.so53646027 D/RESULT: Number of rows extracted = 7368
12-09 06:09:54.493 4845-4858/so53646027.so53646027 D/THREADREPORT: Finished 2nd Test RUN (dropping Index) at 2018-12-09 06:09:54.499+0000
12-09 06:09:54.501 4845-4858/so53646027.so53646027 D/THREADREPORT: Finished at 2018-12-09 06:09:54.505+0000
12-09 06:09:54.501 4845-4858/so53646027.so53646027 D/THREADREPORT: Started at (getting row count)2018-12-09 06:09:50.474+0000
Number of Rows in player_card is 20997 at 2018-12-09 06:09:50.477+0000
Finished Run to ignore chacheing effects at 2018-12-09 06:09:51.858+0000
Finished Test Run without Index (started creating index on card column) at 2018-12-09 06:09:52.969+0000
Finished Creating Index at; Starting Test Run with Index at 2018-12-09 06:09:53.048+0000
Finished 2nd Test Run (now dropping index) at 2018-12-09 06:09:54.499+0000
Finished at 2018-12-09 06:09:54.505+0000
т. Е. На протяжении всего времени я последовательно возвращал 7368 строк.
Поэтому я считаю, что вы можете использовать / конвертировать: -
public void logIt() {
String sql = "SELECT * FROM player_card " +
"WHERE email " +
"In (SELECT email FROM player_card As Tmp " +
" WHERE card = player_card.card " +
" GROUP BY email, card " +
" HAVING COUNT(*) > 1) " +
" ORDER BY email;";
Cursor csr = mDB.rawQuery(sql,null);
Log.d("RESULT","Number of rows extracted = " + String.valueOf(csr.getCount()));
csr.close();