MYSQL基于列数据和表名连接表

时间:2011-11-17 17:29:24

标签: mysql join polymorphic-associations

我想知道这是否可行。

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

我有一张名为hotdog的桌子。

是否有可能像JOIN一样进行JOIN。

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

我知道它不起作用,但它甚至可行,是否有工作?

提前致谢。

2 个答案:

答案 0 :(得分:11)

不,你不能在table1中每行加入一个不同的表,甚至不能像@Cade Roux建议的那样使用动态SQL。

您可以加入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 
...

这要求您了解食物的所有不同值,并且所有相应的食物表都具有相容的列,以便您可以将它们联合起来。

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

有关替代解决方案,请参阅我的答案:

我还在演示文稿Practical Object Oriented Models In SQL和我的书SQL Antipatterns: Avoiding the Pitfalls of Database Programming中介绍了多态关联的解决方案。

答案 1 :(得分: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'

现在你会看到,在SELECT DISTINCT foodtype FROM foods给出关于表名和对表元数据的访问权限的某些假设的情况下,这样的事情可以是代码生成的(甚至是动态的非常慢的原型动态SQL)。

问题在于,无论何时使用此查询的结果,都必须知道每当添加新表时都会显示新列。

所以问题会回到你的客户/消费者的数据 - 它将如何处理不同的类型?对于同一组中的不同类型,它意味着什么?如果它需要知道不同的类型,那么只要为每种类型编写不同的查询,或者在添加新类型时更改手动查询,给出这种更改的相对影响,有什么缺点呢?