Cómo ordenar por nombre y apellido en la barra de búsqueda – Sqlite

Tengo una aplicación de Android que debería reemplazar los contactos originales de Android.

Quiero agregar la posibilidad al usuario de buscar un usuario basado en la restricción de caracteres.

Por ejemplo:

Esta es mi tabla de contactos:

id firstName lastName 1. Smith Jean 2. allen carr 3. zetter 4. john Stewart 5. Smith Allen 6. Smith Davey 7. Smitten 8. barney saltzberg 

Si el usuario introduce el carácter 's' , quiero darle todos los contactos statrting con 's' en su nombre o apellido, ordenados por el nombre primero y luego el apellido. De la tabla antes del resultado que quiero obtener es:

 id firstName lastName 1. Smith Allen 2. Smith Davey 3. Smith Jean 4. barney saltzberg 4. Smitten 5. john Stewart 

ACTUALIZACIÓN: El problema es cuando el primer nombre es igual a NULL, la ordenación no funciona y la fila se muestra antes de que debería. He intentado la respuesta de Marcin y me da el resultado equivocado.

He intentado lo siguiente:

  1. Selección de cadenas = PeopleDataBase.COLUMN_FIRST_NAME + "LIKE '" + restricción + "%" O "+ PeopleDataBase.COLUMN_LAST_NAME +" LIKE' "+ constraint +"% '";

    Cursor cur = db.query (PeopleDataBase.TABLE_PEOPLE, nulo, selección, nulo, nulo, nulo, nulo);

Pensé en lograr esto por dos consultas diferentes, una para el primer nombre y una para el apellido y luego concatenar a un cursor, pero estoy seguro de que hay una mejor solución.

ACTUALIZACIÓN: También intenté ordenar de la siguiente manera sin éxito.

  Cursor cur = db.query(PeopleDataBase.TABLE_PEOPLE, null, selection, null, null, null, PeopleDataBase.COLUMN_FIRST_NAME + "," + PeopleDataBase.COLUMN_LAST_NAME); 

¿Tienes una mejor solución?

¿Cómo se muestran los contactos? En un listview?

Otra idea es cargar todas las entradas en una lista y que se puede filtrar la lista

Puede crear un Listview personalizado e implementar Filterable

 public class YourContactsListAdapter extends BaseAdapter implements Filterable { //some methodes to override @Override public Filter getFilter() { Filter filter = new Filter() { @Override protected FilterResults performFiltering(CharSequence c) {} @Override protected void publishResults(CharSequence charSequence, FilterResults filterResults) {} } } 

Quizás la manera más fácil pero no la mejor. Espero no haber malinterpretado la pregunta.

//EDITAR:

Prueba cursorAdapter no BaseAdapter aquí es un ejemplo … http://tausiq.wordpress.com/2012/08/22/android-list-view-from-database-with-cursor-adapter/

¿Has probado con ORDER BY ?:

 String selection = PeopleDataBase.COLUMN_FIRST_NAME + " LIKE '" + constraint + "%' OR " + PeopleDataBase.COLUMN_LAST_NAME + " LIKE '" + constraint + "%'" ORDER BY " + PeopleDataBase.COLUMN_FIRST_NAME + " ASC, " + PeopleDataBase.COLUMN_LAST_NAME + " ASC"; 

Caso cuando MyDate es null entonces 1 else 0 end PeopleDataBase.COLUMN_FIRST_NAME + ", " + PeopleDataBase.COLUMN_LAST_NAME como el último parámetro de db.query (en lugar de null ) debería funcionar.

EDIT: si desea que los valores nulos sean los últimos que debe seguir: SQL cómo hacer que los valores nulos vienen últimos al clasificar ascendente

a saber:

 Cursor cur = db.query(PeopleDataBase.TABLE_PEOPLE, null, selection, null, null, null, "case when " + PeopleDataBase.COLUMN_FIRST_NAME + " is null then 1 else 0 end," + PeopleDataBase.COLUMN_FIRST_NAME + "," + "case when " + PeopleDataBase.COLUMN_LAST_NAME+ " is null then 1 else 0 end," + PeopleDataBase.COLUMN_LAST_NAME); 

TL, DR

No creo que esto sea fácilmente posible. Considere la posibilidad de relajar sus necesidades.

Secuencia de intercalación personalizada

Si la instalación de secuencias de colación personalizadas en Android era fácilmente posible, sólo tendría que implementar una secuencia de intercalación que haga que null sea ​​igual a cualquier valor. Sin embargo, la instalación de secuencias de intercalación no es posible mediante la API Java Android de sqlite.

Problemas alternativos

¿Puedes alterar tu problema?

  • ¿Sería aceptable que los nombres nulos se clasifiquen primero o por último? Entonces la consulta podría ser algo en la línea de

     select * from contacts where firstname like 's%' or lastname like 's%' order by case when firstname like 's%' then 0 else 1 end, firstname collate nocase, lastname collate nocase; 

    Aquí la primera order by expresión ordena por si el primer nombre coincide o no y luego por nombre y apellido.

  • ¿Algo más para hacer que el problema sea más fácil de resolver?

Pruebas

Primero, preparemos nuestra caja de arena sqlite3:

 sqlite> create table contacts(id integer primary key, firstname text, lastname text); sqlite> insert into contacts values(1,'Smith','Jean'); sqlite> insert into contacts values(2,'allen','carr'); sqlite> insert into contacts values(3,null,'zetter'); sqlite> insert into contacts values(4,'john','Stewart'); sqlite> insert into contacts values(5,'Smith','Allen'); sqlite> insert into contacts values(6,'Smith','Davey'); sqlite> insert into contacts values(7,null,'Smitten'); sqlite> insert into contacts values(8,'barney','saltzberg'); sqlite> .head on 

Tenga en cuenta que obtendrá los resultados de ejemplo que pidió simplemente clasificando por apellido:

 sqlite> select * from contacts where firstname like 's%' or lastname like 's%' order by lastname collate nocase; id|firstname|lastname 5|Smith|Allen 6|Smith|Davey 1|Smith|Jean 8|barney|saltzberg 7||Smitten 4|john|Stewart 

Obviamente esto no es lo que quieres, así que vamos a agregar más datos de prueba a la caja de arena:

 sqlite> insert into contacts values(9,'see','this'); sqlite> select * from contacts where firstname like 's%' or lastname like 's%' order by lastname collate nocase; id|firstname|lastname 5|Smith|Allen 6|Smith|Davey 1|Smith|Jean 8|barney|saltzberg 7||Smitten 4|john|Stewart 9|see|this 

Ahora con esta fila de datos de prueba adicional, la solución de problema alternativa mencionada anteriormente volvería:

 sqlite> select * from contacts where firstname like 's%' or lastname like 's%' order by case when firstname like 's%' then 0 else 1 end, firstname collate nocase, lastname collate nocase; id|firstname|lastname|sortorder 9|see|this| 5|Smith|Allen| 6|Smith|Davey| 1|Smith|Jean| 7||Smitten| 8|barney|saltzberg| 4|john|Stewart| 

Para los resultados del ejemplo "deseado" que has dado, esto parece que va a hacer lo que pides:

 SELECT * FROM contacts WHERE lastname LIKE 's%' OR firstname LIKE 's%' ORDER BY LOWER(lastname), UPPER(firstname); -- rudimentary namesorts via "casing" sqlite> select * from contacts where lastname like 's%' or firstname like 's%' order by lower(lastname), upper(firstname); 16|sadie|| 13|Sarah|| 11|sue|| 5|Smith|Allen| 6|Smith|Davey| 1|Smith|Jean| 10||Saltzberg| 9|Arney|saltzberg| 8|barney|saltzberg| 14|Carnie|Saltzberg| 7||Smitten| 12|Sally|smitten| 4|john|Stewart| 15|Jon|stewart| sqlite> 
  • ¿Cómo acceder a la base de datos cuando se desarrolla en el teléfono Android?
  • Actualizar consulta sqlite - Android
  • Importar archivo .sql en la base de datos sqlite
  • ¿Cómo agregar sub consulta en SQLITE Android junto con 'IN'?
  • OrmLite SQLiteException: ninguna tabla
  • Tabla de actualización de Android sqlite siempre devuelve 0
  • OnUpgrade () base de datos sqlite en Android
  • No se puede capturar Java (Android) Excepción con try-catch
  • Android SQL Lite no crece
  • Cómo importar la biblioteca Persistence Room a un proyecto de Android
  • Cómo agregar la clave principal al tipo de datos de texto en android sqlite?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.