从数据库列填充列表视图,而不重复值

时间:2018-06-06 17:53:40

标签: java android sqlite android-studio listview

我想知道是否可以填写列表视图,不包括重复的单词:

我正在构建一个应用程序,用于存储有关人员的各种信息(姓名,年龄......)。

在我要存储人员国家/地区的其中一列上(输入是textView->字符串),因此每个人都可以写国家/地区,而不必对其进行硬编码。

以后可以阅读数据库,作为选择,我想列出这些国家,所以当你选择一个国家时,那个国家的人就会出现。

问题是,如果我只填写列中的列表,国家/地区将重复显示多次,这就是我想要避免的。

所有国家/地区的输入都是顺序的,所以首先,我考虑制作以国家/地区输入命名的表格并按表名加载它们,但我不知道这是否可行。

我正在使用Android Studio并通过SQLiteOpenHelper处理数据库。谢谢!

2 个答案:

答案 0 :(得分:1)

就我理解你的问题而言,你只需要选择一个合适的数据结构。您需要Set填写您案例中的国家/地区列表。

Set就像ArrayList一样,可以自动管理其密钥的唯一性。我想这会解决你的问题。

我只是为了方便而放置上面提到的教程中的示例。

// Java code for adding elements in Set
import java.util.*;
public class Set_example {
    public static void main(String[] args) {
        // Set deonstration using HashSet
        Set<String> hash_Set = new HashSet<String>();
        hash_Set.add("Geeks");
        hash_Set.add("For");
        hash_Set.add("Geeks");
        hash_Set.add("Example");
        hash_Set.add("Set");
        System.out.print("Set output without the duplicates");

        System.out.println(hash_Set);

        // Set deonstration using TreeSet
        System.out.print("Sorted Set after passing into TreeSet");
        Set<String> tree_Set = new TreeSet<String>(hash_Set);
        System.out.println(tree_Set);
    }
}

答案 1 :(得分:1)

最简单的解决方案是获得 DISTINCT 国家/地区的列表,例如: -

SELECT DISTINCT _country FROM people;
  • 请注意,这是基于人员表,如下所示。

您可以拥有一个国家/地区的二级表,使用触发器自动添加国家/地区。

作为示例,以下SQL演示了这一点: -

DROP TABLE IF EXISTS people;
DROP TABLE IF EXISTS country;
DROP TRIGGER IF EXISTS add_country;
CREATE TABLE IF NOT EXISTS people (_name TEXT, _country TEXT);
CREATE TABLE IF NOT EXISTS country (_country TEXT UNIQUE);
CREATE TRIGGER IF NOT EXISTS add_country AFTER INSERT ON people
    BEGIN 
            INSERT OR IGNORE INTO country VALUES(new._country);
      END;
INSERT INTO people VALUES 
    ('Fred','England'),
    ('Tom','Australia'),
    ('Mary','New Zealand'),
    ('Zoe','France'),
    ('Sarah','England'),
    ('Howard','New Zealand'),
    ('Anne','England');
SELECT * FROM country; 
  • 三个DROP语句仅用于测试目的。
  • 第一个CREATE TABLE语句创建核心表。
  • 第二个CREATE TABLE语句创建免费的国家/地区表。
    • 请注意,用于存储国家/地区的列具有 UNIQUE 约束,因此无法复制值。
  • CREATE TRIGGER语句创建一个触发器,以便在人员表中插入行时,尝试将带有提供的国家/地区的行插入到国家/地区表中。
    • 请注意,如果发生UNQIUE约束,INSERT或IGNORE会忽略失败。
  • INSERT INTO语句在people表中添加了许多行(因此根据触发器添加到country表中)。
  • SELECT语句列表的国家/地区如下: -

enter image description here

您可以使用QUERY,然后根据国家/地区表格作为选择列表的来源,从所选国家/地区提取人员,例如说第三个国家被选中然后是以下QUERY: -

SELECT _name FROM people WHERE _country = (SELECT _country FROM country WHERE rowid = 3); -- 3rd country

会导致: - enter image description here

  • 请注意,您不会使用rowid,因为无法保证它会单调增加。相反,您要么直接使用国家/地区名称,要么使用rowid的别名。
    • rowid用于通过SUB QUERY清楚地证明国家表在WHERE子句中使用。

然而,上述两种解决方案均违反正常化,因为国家/地区将会重复。

虽然稍微复杂一点,但是将rowid的别名(_id INTEGER PRIMARY KEY添加到国家/地区表中)允许引用该国家/地区。下面解释的方法还利用了SQLite列类型的灵活性,并且任何列类型都可以存储任何值,并且仍假设您希望输入 country 而不是选择,则以下内容将替换引用国家/地区表的输入国家/地区(如果存在或不存在),仍会自动插入新的国家/地区

DROP TABLE IF EXISTS people;
DROP TABLE IF EXISTS country;
DROP TRIGGER IF EXISTS add_country;
CREATE TABLE IF NOT EXISTS people (_id INTEGER PRIMARY KEY, _name TEXT, _country TEXT);
CREATE TABLE IF NOT EXISTS country (_id INTEGER PRIMARY KEY, _country TEXT UNIQUE);
CREATE TRIGGER IF NOT EXISTS add_country AFTER INSERT ON people
    BEGIN 
        INSERT OR IGNORE INTO country 
                    VALUES(null,new._country);
              UPDATE people 
                    SET _country = (
                            SELECT _id FROM country WHERE _country = new._country
                        ) 
                        WHERE _country = new._country 
                        AND _name = new._name;
    END;
INSERT INTO people VALUES 
    (null,'Fred','England'),
    (null,'Tom','Australia'),
    (null,'Mary','New Zealand'),
    (null,'Zoe','France'),
    (null,'Sarah','England'),
    (null,'Howard','New Zealand'),
    (null,'Anne','England');
SELECT * FROM country; 
SELECT * FROM people;

。有两个重要的变化/因素: -

  1. 国家/地区表格包含新列 _id ,这是rowid的别名
  2. TRIGGER包括两个动作
    1. 原始插入(_id列为null,因此会自动生成唯一ID)
    2. 更新,它将替换使用相应国家/地区的 _id 输入的国家/地区列,从而通过其ID来引用该国家/地区,从而取消重复的国家/地区。
  3. 上述结果如下: -

    国家/地区表格(SELECT * FROM country;): -

    enter image description here

    表(SELECT * FROM people;): -

    enter image description here

    • 表的 _country 列引用该国家/地区的 _id 列,即使原始输入为 < EM>国家 即可。

    当然,国家1,2,3对最终用户来说没有任何意义,因此为了获得用于演示目的的名称和国家/地区,您可以使用以下内容: -

    SELECT _name, country._country 
    FROM people JOIN country ON people._country = country._id;
    

    哪会导致: -

    enter image description here

    注意;这些解决方案都没有考虑到一个国家可能会拼错。因此,为什么预先定义的国家名单确实是推荐的解决方案。