【问题标题】:How to sort by first name and last name in search bar - Sqlite如何在搜索栏中按名字和姓氏排序 - Sqlite
【发布时间】:2013-05-22 01:08:41
【问题描述】:

我有一个应该替换 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 name 等于 NULL 时,排序不起作用并且该行显示在它应该之前。 我尝试了 marcin 的答案,但它给了我错误的结果。

我尝试了以下方法:

  1. 字符串选择 = PeopleDataBase.COLUMN_FIRST_NAME + " LIKE '" + 约束 + "%' OR " + PeopleDataBase.COLUMN_LAST_NAME + " LIKE '" + 约束 + "%'";

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

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

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

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

你有更好的解决方案吗?

【问题讨论】:

  • 大家好,答案仍然没有帮助我。我想我会以艰难的方式来做,两个不同的查询,然后连接答案。

标签: android sqlite android-contacts


【解决方案1】:

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

另一个想法是在列表视图中加载所有条目,然后您可以过滤列表

您可以创建自定义 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/

【讨论】:

    【解决方案2】:

    你试过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】:

      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】:

        MyDate 为 null 然后 1 else 0 endPeopleDataBase.COLUMN_FIRST_NAME + ", " + PeopleDataBase.COLUMN_LAST_NAME 作为db.query(而不是null)的最后一个参数的情况应该可以工作。

        编辑:如果您希望 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);
        

        【讨论】:

        • 我试过了——“我也试过按以下方式排序 PeopleDataBase.COLUMN_FIRST_NAME, PeopleDataBase.COLUMN_LAST_NAME 没有成功。”。
        • 查询的结果是什么:db.query(PeopleDataBase.TABLE_PEOPLE, null, selection, null, null, null, PeopleDataBase.COLUMN_FIRST_NAME + ", " + PeopleDataBase.COLUMN_LAST_NAME);?
        • 问题是它让我只在该查询中的名字之前与姓氏联系。
        • stackoverflow.com/questions/10254163/… - 它说,用“,”分隔列应该有效。也许尝试在两列中添加“ASC” - 但在我看来它不应该改变任何东西。
        • 你说得对,它有效,但问题是当我与姓氏联系时 - 它在一开始就显示他。
        【解决方案5】:

        对于您给出的“期望”示例结果,这似乎会满足您的要求:

        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>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-09-02
          • 1970-01-01
          • 1970-01-01
          • 2012-10-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多