如何按搜索栏中的名字和姓氏排序 - Sqlite

时间:2013-05-27 07:57:05

标签: android sqlite android-contacts

我有一个Android应用程序,应该取代Android原生联系人。

我希望为用户添加基于字符约束搜索用户的可能性。

例如:

这是我的联系人表格:

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

如果用户输入了字符's',我想向他提供所有与之相关的联系人 's'用他们的名字或姓氏,首先按名字排序,然后按姓氏排序。从我想得到的结果之前的表中可以看出:

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

更新 问题是当First名称等于NULL时,排序不起作用并且行显示在它应该之前。 我尝试了marcin的答案,这给了我错误的结果。

我尝试了以下内容:

  1. 字符串选择= Pe​​opleDataBase.COLUMN_FIRST_NAME +“LIKE”“+约束+”%'或“+ PeopleDataBase.COLUMN_LAST_NAME +”LIKE'“+约束+”%'“;

    Cursor cur = db.query(PeopleDataBase.TABLE_PEOPLE,null,selection,null,null,null,null);

  2. 我想通过两个不同的查询实现这一点,一个用于名字,一个用于姓氏,然后将它们连接到一个游标,但我确信有更好的解决方案。

    更新:我还尝试按以下方式排序,但没有成功。

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

    你有更好的解决方案吗?

5 个答案:

答案 0 :(得分:2)

如何显示联系人?在列表视图中?

另一个想法是加载列表视图中的所有条目,而不是过滤列表

您可以创建自定义Listview并实现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) {}
}
}

也许是最简单但不是最好的方式..希望我没有误解这个问题。

//编辑:

尝试cursorAdapter而不是BaseAdapter这里是一个例子...... http://tausiq.wordpress.com/2012/08/22/android-list-view-from-database-with-cursor-adapter/

答案 1 :(得分:1)

当MyDate为空时,则为1,否则为0结束PeopleDataBase.COLUMN_FIRST_NAME + ", " + PeopleDataBase.COLUMN_LAST_NAME,因为db.query的最后一个参数(而不是null)应该有效。

编辑:如果你想要空值是最后一个,你需要遵循: SQL how to make null values come last when sorting ascending

即:

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);

答案 2 :(得分:1)

您是否尝试使用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";

答案 3 :(得分:1)

TL; DR

我认为这不容易。考虑放宽您的要求。

自定义归类序列

如果可以轻松在Android中安装自定义归类序列,则只需要实现一个归类序列,使null等于任何值。但是,使用sqlite Android Java API无法安装归类序列。

替代问题

你可以改变你的问题吗?

  • null名字首先或最后排序是否可以接受?然后查询可能是

    的内容
    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;
    

    此处第一个order by表达式按名字是否匹配,然后按名字和姓氏排序。

  • 还有什么能让问题更容易解决?

测试

首先,让我们准备我们的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

请注意,您只需按姓氏排序即可获得所要求的示例结果:

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

显然这不是你想要的,所以让我们在沙盒中添加一些测试数据:

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

现在有了这个额外的测试数据行,上面提到的替代问题解决方案将返回:

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|

答案 4 :(得分:1)

对于你所给出的“理想的”示例结果,这似乎就像你要求的那样:

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>