摘要:
我有一个select查询,其中包含我希望满足的where条件。在某些情况下,这个where条件将不被满足,在这种情况下,我想使用一个不同的where条件。这就是我面临的抽象问题。下面是一个更具体的例子:
例子:
我有一个 tag
表和a tag_l11n
table。标记表包含有关标记和 tag_l11n
表包含标记的本地化名称。在下面的简化选择中,我请求使用英文名称的标记( tag_l11n_language = 'en'
)
查询:
SELECT
`tag_3`.`tag_id` as tag_id_3,
`tag_l11n_2`.`tag_l11n_title` as tag_l11n_title_2
FROM
`tag` as tag_3
LEFT JOIN
`tag_l11n` as tag_l11n_2 ON `tag_3`.`tag_id` = `tag_l11n_2`.`tag_l11n_tag`
WHERE
`tag_l11n_2`.`tag_l11n_language` = 'en'
ORDER BY
`tag_3`.`tag_id` ASC
LIMIT 25;
问题:
如果标签没有特定的翻译,问题就开始了。例如,标签可能存在于英语中,但不存在于例如意大利语中。然而,意大利人也会接受英语(或任何其他语言)的标签,如果(当且仅当)意大利语翻译不存在。
最后,我更喜欢一个可以指定不同优先级的解决方案(1。用户本地化。英语,3。任何其他语言)。
我有点不知所措。虽然我可以很容易地忽略条件(language=??)并在输出/表示期间过滤结果,但我不认为这是一种可行的方法。
4条答案
按热度按时间sirbozc51#
你可以在句子中加一个子句
WHERE
如果意大利语翻译不存在,它将使用NOT EXISTS
条款:另一个(可能更高的性能,因为它不会有一个
OR
条件)解决方案是LEFT JOIN
至tag_l11n_2
两次,一次用于所需语言,一次用于备份,并使用COALESCE
要确定所需语言结果的优先级,请执行以下操作:注意:通过添加
LEFT JOIN
和相应的列COALESCE
.dbfiddle上的(两个查询的)演示
puruo6ea2#
如果您运行的是mysql 8.0,我建议您
row_number()
要处理优先级排序:有了这个解决方案,您可以根据需要管理任意级别的优先级,方法是向
ORDER BY
条款ROW_NUMBER()
. 目前这把意大利语翻译放在第一位,然后是英语翻译,然后是任何其他可用的翻译(按字母顺序)。nbewdwxp3#
where条件将left更改为内部联接,导致在没有行的情况下不返回任何行
en
.经典的解决方案使用一种left join perm语言,然后合并得到第一个非空值:
虽然gmb的解决方案在没有默认语言的情况下工作,但是这个解决方案需要默认语言(没有缺少翻译的语言),在您的情况下可能是这样
de
:-)也许gmb的查询可以通过在连接之前应用行号来改进:
这个优先级逻辑也可以用于聚合:
mspsb9vt4#
多亏了@nick answer,我想出了使用函数的新点子
FIELD()
它将覆盖所有可能的语言,而不为每种语言连接单独的表,但有一个子选择。与其他答案相比,我不确定性能如何,但如果用数值来索引语言会比字符串更快(en
,it
等等)。当然,在subselect中应该排除带有null的翻译。