SQL中如何使用CASE语句选择需要关联的表?
基于字段值动态关联多表的SQL实现方案
原代码报错原因
SQL 中的
CASE是值表达式,仅能返回单个结果值,无法在查询运行时动态选择关联的表对象。所有查询涉及的表、列等标识符必须在SQL解析阶段就固定,你原有的写法不符合SQL语法规则,因此无法正常执行。
解决方案1:LEFT JOIN 关联所有可能的表(写法最简单,性能损耗低)
分别关联所有可能用到的属性值表,再通过CASE表达式按需取对应表的字段值即可:
SELECT attribute_names.*, attributes_trans_name.*, CASE attribute_names.c_type WHEN 1 THEN attribute_values_text.c_fk_files_id WHEN 3 THEN attribute_values_longtext.c_fk_files_id WHEN 8 THEN attribute_values_file.c_fk_files_id END AS file_id FROM attribute_names INNER JOIN attributes_trans_name ON attribute_names.c_id = attributes_trans_name.c_fk_attribute_names_id LEFT JOIN attribute_values_text ON attribute_names.c_type = 1 AND attribute_values_text.c_fk_attribute_names_id = attribute_names.c_id LEFT JOIN attribute_values_longtext ON attribute_names.c_type = 3 AND attribute_values_longtext.c_fk_attribute_names_id = attribute_names.c_id LEFT JOIN attribute_values_file ON attribute_names.c_type = 8 AND attribute_values_file.c_fk_attribute_names_id = attribute_names.c_id
这种写法利用LEFT JOIN的条件先过滤匹配的c_type,不会出现多余的关联结果,逻辑简单易维护。
解决方案2:UNION ALL 合并值表后关联(适合值表结构统一的场景)
如果三个属性值表的字段结构高度相似,可以先把它们合并为一个虚拟表再关联,代码更简洁:
SELECT an.*, atn.*, av.file_id FROM attribute_names an INNER JOIN attributes_trans_name atn ON an.c_id = atn.c_fk_attribute_names_id INNER JOIN ( SELECT 1 AS c_type, c_fk_attribute_names_id, c_fk_files_id AS file_id FROM attribute_values_text UNION ALL SELECT 3 AS c_type, c_fk_attribute_names_id, c_fk_files_id AS file_id FROM attribute_values_longtext UNION ALL SELECT 8 AS c_type, c_fk_attribute_names_id, c_fk_files_id AS file_id FROM attribute_values_file ) av ON av.c_type = an.c_type AND av.c_fk_attribute_names_id = an.c_id
内容的提问来源于stack exchange,提问作者M Usman
相关产品推荐
相关产品推荐

