我有一个table_a
,它有两个外键到表options
的主键。
我SELECT
基于@_aValue
等于options
中table_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中工作。
答案 0 :(得分:3)
我认为你不能摆脱条件逻辑。但是,我认为你可以简化一下查询。第一个想法是使用LEFT JOIN
和COALESCE()
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
,如果两个表的格式完全相同,则可以使用*
。