我正在开发使用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
数据库中的多个条目可以具有相同的代码值和不同的语言值。
我的条件如下:
我应该至少有一个代码值的记录。
我必须根据自己想要的语言进行搜索。假设我将语言作为西班牙语,我应该获得所有西班牙语的记录。
如果我提供的任何代码条目没有给定的语言,那么我应该获得该代码的英文条目。
如果任何代码条目只有一条记录使用一种语言,那么无论我给出的语言如何,我都应该得到该记录。
上表中我的预期结果:
如果我将语言作为西班牙语: -
3 | 1 | Spanish | ccc
5 | 2 | English | eee
7 | 3 | English | ggg
8 | 4 | French | hhh
我应该有1,2,3,4个代码值。
语言西班牙语代码为1我有西班牙语记录,所以它应该来了。
使用代码为2的西班牙语语言我没有西班牙语记录,因此应该选择代码为2和语言英语的记录。
Code 3& 4条记录只有一个条目,所以这些记录应该来。
我在网上搜索了很多关于如何在类似的行上操纵这些条件,但我无法得到答案。有人可以通过查询预期结果来帮助我。
提前致谢。
答案 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)
警告:我没有测试这些查询的正确性或性能。