基于列枚举值创建SQL语句

时间:2012-05-29 16:00:52

标签: mysql sql database-design architecture enums

假设我有一个名为normalize的表,其中包含一个名为type

的枚举列

取决于行(假设类型是a,b或c)我想根据类型进行LEFT JOIN。

所以,如果type = a,LEFT JOIN ON表a ..如果type = B,LEFT JOIN ON table b ... etc

这可以有效地完成吗?或者应该在应用层完成?

4 个答案:

答案 0 :(得分:1)

是的,您应该能够做到这样的事情:

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 :(得分:0)

一种常见方法是将类型存储为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

因此,bt1中条目的实体必须为类型1. bt2中条目的实体属于类型2。这样,信息只存储一次,并且表格会说“类型1”但t1中没有匹配的行的不一致性是不可能的。

答案 2 :(得分:0)

问题在于即使您使用SELECT table1.* FROM table1 LEFT OUTER JOIN table2,即使您甚至不需要显示它们,引擎也会评估连接。

因此,我认为有两种选择:

  • 1st:假设连接有效,使用适当的索引和可接受的I / O,并使用以下查询:

**见下面,列在它的列表中**

  • 假设做n个连接,n是不同类型的数量(如果每个类型有一个表),会产生很多开销,然后在应用层进行2次查询:第一个获取类型,然后是另一个在switch case语句中,例如从右表中检索数据。

解释计划也可以给你一个很好的线索,你正在做什么

查询:

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 ...

答案 3 :(得分:0)

不确定这是否有帮助,但我可能会使用联盟来执行您正在寻找的内容

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