从sqlite3数据库中的多个类似记录中条件选择单个记录

时间:2012-06-28 06:58:59

标签: android sqlite

我正在开发使用Sqlite3数据库进行存储的android应用程序。

最近我遇到了一个问题,我需要根据我在特定列上的条件从多个相似的行中选择一行。

更具体一点......

来源数据:

_id | code | language | data

 1  | 1    | English  | aaa

 2  | 1    | French   | bbb

 3  | 1    | Spanish  | ccc

 4  | 1    | Portuguse| ddd

 5  | 2    | English  | eee

 6  | 2    | French   | fff

 7  | 3    | English  | ggg

 8  | 4    | French   | hhh

数据库中的多个条目可以具有相同的代码值和不同的语言值。

我的条件如下:

  1. 我应该至少有一个代码值的记录。

  2. 我必须根据自己想要的语言进行搜索。假设我将语言作为西班牙语,我应该获得所有西班牙语的记录。

  3. 如果我提供的任何代码条目没有给定的语言,那么我应该获得该代码的英文条目。

  4. 如果任何代码条目只有一条记录使用一种语言,那么无论我给出的语言如何,我都应该得到该记录。

  5. 上表中我的预期结果:

    如果我将语言作为西班牙语: -

    3  | 1    | Spanish  | ccc
    
    5  | 2    | English  | eee
    
    7  | 3    | English  | ggg
    
    8  | 4    | French   | hhh
    
    1. 我应该有1,2,3,4个代码值。

    2. 语言西班牙语代码为1我有西班牙语记录,所以它应该来了。

    3. 使用代码为2的西班牙语语言我没有西班牙语记录,因此应该选择代码为2和语言英语的记录。

    4. Code 3& 4条记录只有一个条目,所以这些记录应该来。

    5. 我在网上搜索了很多关于如何在类似的行上操纵这些条件,但我无法得到答案。有人可以通过查询预期结果来帮助我。

      提前致谢。

1 个答案:

答案 0 :(得分:0)

如果你需要在一个怪物查询中完成它,这里有一种基于外连接几个子查询的方法。 假设:(code, language)是一个唯一的密钥;所有列均为NOT NULL


首先,规则1说每个代码都需要在最终结果中表示。让all_codes成为提供每个唯一代码的子查询:

(select code 
   from my_table 
  group by code) all_codes

接下来,规则2说任何具有所需语言的行都需要存在。让matches成为提供这些行的子查询:

(select _id, code, language, data 
   from my_table 
  where language = ?) matches

接下来,规则3说,如果没有所需的语言,请回到英语。让en_fallbacks成为提供这些行的子查询:

(select _id, code, language, data 
   from my_table 
  where language = 'English') en_fallbacks

规则4表示特定代码的任何单例记录都应存在于结果中。让singletons成为提供这些行的子查询:

(select MIN(_id) as _id, code, MIN(language) as language, MIN(data) as data 
   from my_table 
  group by code 
 having (MIN(_id) = MAX(_id))) singletons

最后,在共享的code列中按顺序将它们连接在一起,然后使用COALESCE获取所需的列值:

select all_codes.code,
       COALESCE(matches._id, en_fallbacks._id, singletons._id) as _id,
       COALESCE(matches.language, en_fallbacks.language, singletons.language) as language,
       COALESCE(matches.data, en_fallbacks.data, singletons.data) as data
  from (...) all_codes
       left outer join (...) matches on (all_codes.code = matches.code)
       left outer join (...) en_fallbacks on (all_codes.code = en_fallbacks.code)
       left outer join (...) singletons on (all_codes.code = singletons.code)

警告:我没有测试这些查询的正确性或性能。