2011-11-17 46 views
8

我想知道这是否是偶数。基于列数据和表名的MYSQL连接表

我想根据表1的数据加入2个表格。 示例表格1的列食物的数据为“热狗”。

我有一张叫做热狗的表。

有没有可能做一个联接像。

SELECT * FROM table1 t join t.food on id = foodid 

我知道它不起作用,但它甚至可能是有工作的吗?

在此先感谢。

+1

这似乎更像是一个设计问题 - 如果直到运行时才知道自己的连接,您将如何执行参照完整性? – tomfumb

回答

9

不,你不能加入到每行不同的表中table1,即使不使用动态SQL作为@Cade鲁建议。

您可以加入到hotdog表行,其中食品是“热狗”,并加入到其他表用于食品的其他特定值。

SELECT * FROM table1 JOIN hotdog ON id = foodid WHERE food = 'hotdog' 
UNION 
SELECT * FROM table1 JOIN apples ON id = foodid WHERE food = 'apples' 
UNION 
SELECT * FROM table1 JOIN soups ON id = foodid WHERE food = 'soup' 
UNION 
... 

这就要求你知道食物的所有不同的值,并且所有相应的食物成分表兼容列,因此您可以UNION在一起。

你在做什么叫做多态关联。也就是说,table1中的外键引用了多个“父”表中的行,具体取决于table1的另一列中的值。这是关系数据库程序员常见的设计错误。

其他解决方案,请参阅我的答案:

我还涵盖了多态关联的解决方案在我的介绍Practical Object Oriented Models In SQL,并在我的书SQL Antipatterns: Avoiding the Pitfalls of Database Programming

0

仅适用于动态SQL。也可以将许多不同的表格留在一起,并根据类型使用CASE,但表格必须事先知道。

这将是更容易提出适当的设计,如果我们知道更多关于你想达到什么样的,你选择你的设计目前看起来,为什么在首位特定表的设计。

Say you have a table of foods: 

id INT 
foodtype VARCHAR(50) (right now it just contains 'hotdog' or 'hamburger') 
name VARCHAR(50) 

Then hotdogs: 

id INT 
length INT 
width INT 

Then hamburgers: 

id INT 
radius INT 
thickness INT 

通常我会推荐一些制度约束只是一个辅助表中存在,但为了简单起见,我离开了这一点。

SELECT f.*, hd.length, hd.width, hb.radius, hb.thickness 
FROM foods f 
LEFT JOIN hotdogs hd 
    ON hd.id = f.id 
    AND f.foodtype = 'hotdog' 
LEFT JOIN hamburgers hb 
    ON hb.id = f.id 
    AND f.foodtype = 'hamburger' 

现在你会看到,可以产生这样的事情代码(甚至在飞行一个非常缓慢的原型动态SQL)约表名和访问表元数据SELECT DISTINCT foodtype FROM foods给予一定的假设。

的问题是,谁最终消耗此查询的结果将必须知道显示出来,一旦添加新表新列。

所以问题移回数据的客户端/消费 - 究竟是怎样处理不同类型的?对于不同的类型,它们在同一个集合中意味着什么?如果需要了解不同的类型,那么只要为每种类型编写不同的查询,或者在添加新类型时更改手动查询,给定这种更改的相对影响,有什么缺点?

+0

为重播的问题.... 我喜欢联盟解决方案认为即时通讯不知道实施它的热点。所以继承人的细节。 学生对一些信件进行请求,在表格“请求”上,学生的数据和“字母类型”被保存。 Theres 10种不同的“字母类型”的可能值。所以我有10个表与特定的字母类型名称,如.. 表推荐, 表转移, 所以我想要一种方法来做所有的查询1基于学生的信,要调用特定的表和从中获取数据。 – user1052347

+0

@ user1052347 Bill Karwin给出了几个设计链接。最终,因为每种类型的关联数据都不相同,所以实际的“SELECT *”不太可能起作用,因为每个表中的辅助信息将会不同。你需要决定你想要结果集的样子。此时,您可以手工编写代码(或者甚至可能生成代码/动态SQL - 从而在某种程度上消除了更改模式时的维护问题)。我会在我的答案中举一个例子。 –