假设我有一个名为 normalize 的表,其中有一个名为 type 的枚举列
根据行(假设类型是 a、b 或 c),我想根据类型进行 LEFT JOIN。
因此,如果 type = a,则 LEFT JOIN ON 表 a .. 如果 type = B,LEFT JOIN ON 表 b ...等
这可以有效地完成吗?还是应该在应用层完成?
假设我有一个名为 normalize 的表,其中有一个名为 type 的枚举列
根据行(假设类型是 a、b 或 c),我想根据类型进行 LEFT JOIN。
因此,如果 type = a,则 LEFT JOIN ON 表 a .. 如果 type = B,LEFT JOIN ON 表 b ...等
这可以有效地完成吗?还是应该在应用层完成?
是的,您应该能够执行以下操作:
SELECT *
FROM parent
LEFT JOIN a ON (type = 'a' AND parent.id = a.id)
LEFT JOIN b ON (type = 'b' AND parent.id = b.id)
LEFT JOIN c ON (type = 'c' AND parent.id = c.id)
您可能需要也可能不需要索引type
,具体取决于实际数据和您的 DBMS 的智能程度(利用应该存在于 PK 下的索引)。无论如何,测量真实的数据量。
一种常见的方法是将类型存储为 1:1 关系。在这种方法中,没有类型枚举列。ID 出现在 1:1 扩展表中的事实表明了它的类型。
select *
from BaseTable b
left join
Type1Table t1
on t1.Id = b.Id
left join
Type1Table t2
on t2.Id = b.Id
因此,具有inb
和int1
条目的实体必须是类型 1。具有 inb
和 in条目的实体t2
属于类型 2。这样,信息只存储一次,并且表会显示“类型 1”但不一致没有匹配的行t1
是不可能的。
问题是,即使您使用SELECT table1.* FROM table1 LEFT OUTER JOIN table2
,引擎也会评估连接,即使您甚至不需要显示它们。
所以,在我看来,有两种选择:
** 见下文,在它的错误列表中 **
解释计划也可以让你很好地了解你在做什么
询问:
SELECT
IF(t.type = a, ta.value,
IF(type = b, tb.value, IF(type = c, tc.value, td.value))
)
FROM
table t
LEFT JOIN type_a_table ta ON t.type = a AND ...
LEFT JOIN type_a_table tb ON t.type = b AND ...
LEFT JOIN type_a_table tc ON t.type = c AND ...
LEFT JOIN type_a_table td ON t.type = d AND ...
不确定这是否有帮助,但我可能会使用联合来执行您正在寻找的内容
select *
from BaseTable b left join TypeTableA a on b.id = a.id
union
select *
from BaseTable b left join TypeTableB b on b.id = b.id