1

我正在开发使用 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. 如果任何代码条目只有一种语言的记录,那么无论我给出的语言如何,我都应该得到该记录。

我对上表的预期结果:

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

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. 代码 3 和 4 记录只有一个条目,所以这些记录应该来。

我在网上搜索了很多关于如何在类似行上操作这些条件的信息,但我无法得到答案。有人可以帮助我查询预期结果吗?

提前致谢。

4

1 回答 1

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)

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

于 2012-06-28T16:21:50.883 回答