简化SELECT中的多个CASE调用

时间:2014-11-22 01:26:38

标签: mysql sql case mariadb

我有一个table_a,它有两个外键到表options的主键。

SELECT基于@_aValue等于optionstable_a个主键中的任何一个。如果我停在那里,我会得到一个表,其中表a中的每一行都有两组选项。我只对主键等于@_aValue的选项感兴趣,所以只有一组这些选项,但我事先并不知道table_a中哪两个值属于哪个至。此外,我有兴趣按照它们在数据库中的顺序检索所有行,在我看来,这将产生两个查询,其结果必须排序不理想。我已经实现了一个有效的解决方案,但我认为这是非常低效的,因为它对每行执行多次相同的CASE比较:

SELECT
    (CASE a.a_id_1 WHEN @_aValue THEN options_a.value_1 ELSE options_b.value_1 END) AS value_1,
    (CASE a.a_id_1 WHEN @_aValue THEN options_a.value_2 ELSE options_b.value_2 END) AS value_2,
    (CASE a.a_id_1 WHEN @_aValue THEN options_a.value_3 ELSE options_b.value_3 END) AS value_3,
FROM table_a AS a
INNER JOIN options AS options_a
    ON a.a_id_1 = options_a.options_id
INNER JOIN connection_details AS details_b
    ON a.a_id_2 = options_b.options_id
WHERE a.a_id_1 = @_aValue
    OR a.a_id_2 = @_aValue;

在我当前版本中实际上有更多CASE次比较。有没有办法进行一次比较,并根据选择options_a的值或options_b的值?理想情况下,解决方案符合标准,但如果不可行,我需要它在当前版本的MySQL和MariaDB 5.3中工作。

1 个答案:

答案 0 :(得分:3)

我认为你不能摆脱条件逻辑。但是,我认为你可以简化一下查询。第一个想法是使用LEFT JOINCOALESCE()

SELECT COALESCE(options_a.value_1, options_b.value_1) AS value_1,
       COALESCE(options_a.value_2, options_b.value_2) AS value_2,
       COALESCE(options_a.value_3, options_b.value_3) AS value_3
FROM table_a a LEFT JOIN
     options options_a
     ON a.a_id_1 = options_a.options_id AND
        a.a_id_1 = @_aValue LEFT JOIN
     connection_details details_b
     ON a.a_id_2 = options_b.options_id AND
        a.a_id_1 <> @_aValue
WHERE @_aValue IN (a.a_id_1, a.a_id_2);

实际上,更简单的方法:

SELECT o.value_1, o.value_2, o.value_3 AS value_3
FROM table_a a JOIN
     ((SELECT 'a' as which, oa.options_id, oa.value_1, oa.value_2, oa.value_3
       FROM options_a oa
       WHERE options_id = @_aValue
      ) UNION ALL
      (SELECT 'b' as which, cd.options_id, cd.value_1, cd.value_2, cd.value_3
       FROM connection_details cd
       WHERE options_id <> @_aValue
      )
     ) o
     ON a.a_id_1 = @_aValue or a.a_aid_2 = o.options_id
 WHERE @_aValue IN (a.a_id_1, a.a_id_2);

(我认为on条件正确,但我对WHERE有点担心。)

对于union all,如果两个表的格式完全相同,则可以使用*