2010-07-26 13 views
2

Je veux créer un Cursor, qui plus tard, je vais passer par CursorAdapter à AutoCompleteTextView pour les suggestions d'auto-complétion. Le problème est que mon instruction SQL doit sélectionner 2 ensembles de résultats différents à partir de la même table, juste triés par des critères différents. En même temps, ces ensembles de résultats ne doivent pas se chevaucher - sinon, j'aurais plusieurs suggestions identiques. Sur MySQL, ce serait assez facile:SQLite sur Android: Union avec des limites alternatives

(SELECT field3 FROM table ORDER BY field1 ASC LIMIT 5) 
UNION 
(SELECT field3 FROM table ORDER BY field2 DESC LIMIT 10) 
LIMIT 10 

Dans ce cas, j'aurais toujours jusqu'à 10 valeurs uniques. Sur SQLite, malheureusement, ce n'est pas le cas - je ne peux pas avoir de limites sur des sélections particulières, juste sur l'ensemble des résultats, ce qui fait que UNION n'est pas utile pour ce cas ...

Pour résoudre ce problème Nous avons pensé à faire 2 requêtes séparément: itérer Cursor depuis la 1ère requête et placer les valeurs dans Array, puis parcourir Cursor à partir de la 2ème requête et également placer les valeurs dans le même tableau tout en vérifiant et en ignorant les valeurs déjà existantes dans Array pour éviter les doublons. Ensuite, utilisez ArrayAdapter pour transmettre les valeurs à AutoCompleteTextView.

Théoriquement, cela fonctionnerait - mais ce que je n'aime pas que tout devient plus complexe et beaucoup plus de code à écrire pour résoudre une telle tâche simple ...

Est-il peut-être une meilleure et plus facile à faire il?

Répondre

2

Avez-vous envisagé de créer une limite d'intelligence artificielle pour sélectionner à partir du milieu du jeu d'enregistrements. Permettez-moi de présenter l'idée dans un exemple

D'abord vous voulez sélectionner dans la première requête les 5 premiers enregistrements. Rendre l'ordre inversé afin qu'il apparaisse à la fin du jeu d'enregistrements. Aucune limite appliquée ici.

SELECT field3 FROM table ORDER BY field1 DESC 

Exemple:

field1 | field2 
12  x 
11  x 
9  x 
8  x 
7  x 
6  x 
5  x 
4  x 
3  x 
2  x 
1  x 

font ensuite la deuxième requête dans l'ordre que vous voulez. Aucune limite appliquée ici.

SELECT field3 FROM table ORDER BY field2 DESC 

Ensuite, faire une union sur les

(SELECT field3 FROM table ORDER BY field1 DESC) 
UNION 
(SELECT field3 FROM table ORDER BY field2 DESC) 

Les résultats que vous voulez êtes au milieu du resultset

field1 | field2 
11  x 
10  x 
9  x 
8  x 
7  x 
6  x 
---------- 
5  x 
4  x 
3  x 
2  x 
1  x 
x  1 
x  2 
x  3 
x  4 
x  5 
x  6 
x  7 
x  8 
x  9 
x  10 
---------- 
x  11 

Vous pouvez maintenant appliquer un décalage et limite à votre question. Pour ce travail, vous devez interroger le nombre d'enregistrements dans votre table qui sont éligibles pour que la requête fonctionne.

La requête finale serait quelque chose comme:

(SELECT field3 FROM table ORDER BY field1 DESC) 
UNION 
(SELECT field3 FROM table ORDER BY field2 DESC) 
LIMIT 5+10 OFFSET N-5 

J'ai écrit le LIMITS explicitement pour être en mesure de calculer vous-même, décalage N-5 signifie sauter N-5 enregistrements depuis le début du jeu d'enregistrements.

+1

Bonne idée! Mais SQLite ne permet pas non plus d'utiliser 'ORDER BY' dans les instructions multi-select ni:' Erreur SQL: la clause ORDER BY devrait venir après UNION pas avant ' – Laimoncijus

1

Ce qui suit vous donnera les mêmes résultats que votre exemple MySQL:

CREATE TABLE IF NOT EXISTS unionTemp (field3 TEXT) 
DELETE FROM unionTemp 

INSERT INTO unionTemp SELECT field3 FROM table ORDER BY field1 ASC LIMIT 5 
INSERT INTO unionTemp SELECT field3 FROM table ORDER BY field2 ASC LIMIT 10 

SELECT field3 FROM unionTemp GROUP BY field3 LIMIT 10 

Vous voudrez peut-être utiliser une table temporaire. (CREATE TEMP TABLE ...)