例:
> SELECT name, culture FROM city_i18n WHERE ID = 2745;
+-------+---------+
| name | culture |
+-------+---------+
| Paris | en_GB |
| París | es_ES |
| Paris | pt_BR |
| Paris | pt_PT |
+-------+---------+
4 rows in set (0.00 sec)
> SELECT DISTINCT name FROM city_i18n WHERE ID = 2745 AND culture IN ('es_ES', 'en_GB');
+-------+
| name |
+-------+
| Paris |
+-------+
1 row in set (0.00 sec)
> SELECT DISTINCT name FROM city_i18n WHERE ID = 2745 AND culture IN ('es_ES', 'pt_PT');
+-------+
| name |
+-------+
| París |
+-------+
1 row in set (0.00 sec)
请注意两个SELECT DISTINCT的不同输出:巴黎,巴黎(带有重音符号)
现在,有什么简单的方法可以始终赋予es_ES优先级(即始终使带有重音符号的París)?
由于存在疑问,需要进行一些澄清:仅重音(根据排序规则)不同的城市名称应只显示一次.在这种情况下,显示的名称应具有文化es_ES的重音.
解决方法:
问题是数据库中使用的排序规则序列.根据您的RDBMS,那里有大量有关整理序列的信息.在更改排序规则序列时,您需要非常小心,因为它可能会产生意外的结果.
排序顺序用于测试列的相等性或不相等性.根据所使用的排序规则,以下语句可能全部为true或false:
'TexT' = 'text'
'TEXT' = 'text'
'áéíóú' = 'aeiou'
在您的情况下,您需要选择一个排序规则序列,它将重音字母和常规字母视为不同的值.当前,您的数据库正在确定它们相等.一旦有了适当的选择,您就可以开发自己的逻辑,以便根据自己喜欢的文化选择合适的价值
只是要补充一下,您的数据库似乎正在确定Paris =Parísand,我怀疑不能保证将选择哪个不同的值,这类似于以下事实:除非确定ORDER BY子句,否则结果集没有确定的顺序用过的.
我考虑了一段时间.我认为最好的办法是创建一个CultureRank
CREATE TABLE CultureRank
(
Rank INTEGER,
Culture VARCHAR(5)
);
INSERT INTO CultureRank VALUES (1, 'es_ES');
INSERT INTO CultureRank VALUES (2, 'en_GB');
INSERT INTO CultureRank VALUES (3, 'pt_BR');
INSERT INTO CultureRank VALUES (4, 'pt_PT');
SELECT
Name
FROM
City_i18n
LEFT JOIN CultureRank ON City_i18n.Culture = CultureRank.Culture
WHERE
ID = 2745
AND City_i18n.Culture IN ('es_ES', 'pt_PT') -- If Required
ORDER BY
IF(ISNULL(CultureRank.Culture),1,0),
CultureRank.Rank
LIMIT 1;
如果city_i18n中的文化不在CultureRank中,则需要ORDER BY ISNULL.此处的IsNull函数将确保CultureRank表中的区域性被赋予最高优先级,然后,如果这些都不与城市相关联,则引擎将从city_i18n表中为该城市选择随机区域性.如果您希望不在CultureRank中的文化成为重中之重,则将1& ISNULL函数中的参数为0.
编辑:
SELECT
Name
FROM
City_i18n
LEFT JOIN CultureRank ON City_i18n.Culture = CultureRank.Culture
WHERE
ID = 2745
AND City_i18n.Culture IN ('es_ES', 'pt_PT') -- If Required
AND NOT EXISTS (
SELECT
NULL
FROM
City_i18n Cities
LEFT JOIN CultureRank CitiesRank ON Cities.Culture = CitiesRank.Culture
WHERE
City_i18n.Name = Cities.Name
AND CultureRank.Rank < CitiesRank.Rank)
这应该使您从City_i18n表中获得给定ID的每个名称,除非根据您的排序规则序列,在CultureRank表中具有较高排名的另一个具有相同名称的记录.