首页 > 解决方案 > 带有条件 WHERE 子句的 SQL SELECT

问题描述

抽象的:

我有一个 SELECT 查询,其中包含我希望满足的 WHERE 条件。在某些情况下,不会满足这个 WHERE 条件,在这种情况下,我想使用不同的 WHERE 条件。这就是我面临的抽象问题。这是一个更具体的例子:

例子:

我有一张tag桌子和一张tag_l11n桌子。标签表包含有关标签的基本信息,并且该tag_l11n表包含标签的本地化名称。在以下简化的 SELECT 中,我请求使用英文名称 ( 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;

问题:

如果标签没有特定的翻译,问题就开始了。例如,标签可能存在于英语中,但不存在于意大利语中。但是,意大利人也会接受英语(或任何其他语言)IFF(当且仅当)意大利语翻译不存在的标签。

最后,我更喜欢一个可以指定不同优先级的解决方案(1. 用户本地化,2. 英语,3. 任何其他语言)。

我在这里有点不知所措。虽然我可以轻松地省略条件(语言 = ??)并在输出/演示期间过滤结果,但我认为这不是要走的路。

标签: mysqlsql

解决方案


WHERE如果意大利语翻译不存在,您可以添加一个子句,该子句将返回英文翻译,使用NOT EXISTS子句:

WHERE 
    `tag_l11n_2`.`tag_l11n_language` = 'it' 
OR
    `tag_l11n_2`.`tag_l11n_language` = 'en'
    AND NOT EXISTS (SELECT *
                    FROM tag_l11n t3 
                    WHERE t3.tag_l11n_tag = tag_3.tag_id 
                      AND t3.tag_l11n_language = 'it')

另一个(可能性能更高,因为它没有OR条件)解决方案是LEFT JOIN两次tag_l11n_2,一次用于所需语言,一次用于备份,并使用COALESCE来确定所需语言结果的优先级:

SELECT 
    `tag_3`.`tag_id` as tag_id_3,
    COALESCE(`tag_l11n_2`.`tag_l11n_title`, `tag_l11n_3`.`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` 
                            AND `tag_l11n_2`.`tag_l11n_language` = 'it' 
LEFT JOIN 
    `tag_l11n` as tag_l11n_3 ON `tag_3`.`tag_id` = `tag_l11n_3`.`tag_l11n_tag` 
                            AND `tag_l11n_3`.`tag_l11n_language` = 'en' 
ORDER BY 
    `tag_3`.`tag_id` ASC 
LIMIT 25;

请注意,通过将LEFT JOINs 和适当的列添加到COALESCE.

dbfiddle 上的演示(两个查询)


推荐阅读