简体   繁体   English

根据列枚举值创建SQL语句

[英]Creating a SQL statement based on a column enum value

Let's assume I have a table called normalize with an enum column called type 假设我有一个名为normalize的表,该表带有一个名为type的枚举列

Depending on the row (Let's assume the types are a, b or c) I want to do a LEFT JOIN based on whatever the type is. 根据行的不同(让我们假设类型是a,b或c),我想基于任何类型进行LEFT JOIN。

So, if type = a, LEFT JOIN ON table a .. if type = B, LEFT JOIN ON table b... etc 因此,如果类型= a,则在表a上为LEFT JOIN ON ..如果类型= B,则在表b上为LEFT JOIN ON ...等等

Can this be done efficiently? 可以有效地做到这一点吗? Or should this be done at the application layer? 还是应该在应用程序层完成?

Yes, you should be able to do something like this: 是的,您应该可以执行以下操作:

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)

You may or may not need an index on type , depending on the actual data and how smart your DBMS is (in exploiting indexes that ought to exist underneath PKs). 您可能需要也可能不需要type索引,具体取决于实际数据和DBMS的智能程度(利用PK下应存在的索引)。 In any case, measure on realistic amounts of data. 无论如何,都要根据实际数据量进行度量

One common approach is to store the type as a 1:1 relation. 一种常见的方法是将类型存储为1:1关系。 In this approach, there is no type enum column. 在这种方法中,没有类型枚举列。 The fact that an ID is present in a 1:1 extension table indicates its type. 1:1扩展表中存在ID的事实表示其类型。

select  *
from    BaseTable b
left join
        Type1Table t1
on      t1.Id = b.Id
left join
        Type1Table t2
on      t2.Id = b.Id

So an entity with an entry in b and t1 must be of type 1. An entity with an entry in b and in t2 is of type 2. That way, the information is only stored once, and an inconsistency where the table would say "type 1" but there was no matching row in t1 is impossible. 因此,在bt1具有条目的实体必须是类型1。在bt2具有条目的实体必须是类型2。这样,信息仅存储一次,并且表中的不一致之处是“类型1”,但在t1没有匹配的行是不可能的。

The problem is that even if you use SELECT table1.* FROM table1 LEFT OUTER JOIN table2 , the engine will evaluate the join even though you don't even need to show them. 问题在于,即使您使用SELECT table1.* FROM table1 LEFT OUTER JOIN table2 ,即使您甚至不需要显示连接,引擎也会评估连接。

So, in my opinion there are 2 options: 因此,我认为有两种选择:

  • 1st: Assume the joins are effective, using proper indexes and with an acceptable I/O, and use the following query: 1st:假定联接有效,使用适当的索引并具有可接受的I / O,并使用以下查询:

** SEE BELOW, WITHIN THE LIST IT BUGS ** **在清单中发现以下错误**

  • Assume doing n joins, n being the number of different type (if there's a table per type), would give to much overhead, and then procede at the applicative layer with 2 queries: the first to get the type and then another within a switch case statement for example to retrieve datas from the right table. 假设执行n个连接,n是不同类型的数量(如果每种类型都有一个表),将产生很大的开销,然后在应用层进行两次查询:第一个获取类型,然后在开关内进行另一个例如case语句,用于从右表中检索数据。

Explain plan also could give you a good clue of what you're doing 说明计划也可以为您提供一个很好的线索

Query: 查询:

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

Not sure if this helps, but I would probably use a union to perform what you're looking for 不确定这是否有帮助,但是我可能会使用联合来执行您要查找的内容

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM