基于列值的条件连接

4

我正在尝试根据事件类型有条件地将一个主事件表连接到另外三个表。选择语句可以正常工作,返回了我期望的结果集,但是当我添加JOIN语句时,出现了错误,提示找不到列别名:

SELECT 
event.type as type,
IF(type = 'birthday', event.target_id, NULL) as birthday_id,
IF(type = 'graduation', event.target_id, NULL) as graduation_id,
IF(type = 'wedding', event.target_id, NULL) as wedding_id
FROM event
LEFT OUTER JOIN birthday ON birthday_id = birthday.id
LEFT OUTER JOIN graduation ON graduation_id = graduation.id
LEFT OUTER JOIN wedding ON wedding_id = wedding.id

出现以下错误:

在“on”子句中未知列“birthday_id”


更新:好的,Sebas刚刚指出您无法在计算结果上进行连接,那么我这种方法就行不通了。那么像这样做正确的方法是什么?


你介意为我们添加别名吗?这样我们可以更好地查看查询。 - Sebas
1
哦,你不能加入计算结果,我会发布一个答案。 - Sebas
回答已发布!请注意,我认为您实际上想显示事件类型和相应的事件ID,而不是NULL NULL weddingID(例如)。这也是可能的。 - Sebas
3个回答

5
SELECT 
    event.type as type,
    IF(type = 'birthday', birthday.id, NULL) as birthday_id,
    IF(type = 'graduation', graduation.id, NULL) as graduation_id,
    IF(type = 'wedding', wedding.id, NULL) as wedding_id
FROM 
    event
        LEFT OUTER JOIN birthday b  ON event.target_id = b.id
        LEFT OUTER JOIN graduation g    ON b.id IS NULL AND event.target_id = g.id
        LEFT OUTER JOIN wedding w   ON b.id IS NULL AND g.id IS NULL AND event.target_id = w.id

这应该能解决问题,请给我反馈!

编辑:请看IS NULL条件。我没有测试过,不知道MySQL是否接受它!如果是的话,那么几乎只需要进行必要的连接...


谢谢Sebas-所以如果每个表都有一个与目标id匹配的id,这实际上会连接所有三个表,对吗?我猜它会起作用,但似乎效率很低... - Yarin
嗯,让我想到了什么, 请看即将到来的更新。 - Sebas
不知道那个更新是否可行,但我认为 SQL 语句已经太复杂了...这可能需要使用子查询来完成 - 不管怎样,感谢您的耐心等待和努力。 - Yarin
不客气!我相当确定我们应该重新表达原始需求,因为我认为存在一个概念上的问题,即展示事件类型,然后是生日、毕业和婚礼,尽管这与关注点无关。敬礼。 - Sebas

1

您需要使用相同的字段event.target_id连接所有表格,当您需要显示特定数据时,可以先进行类型测试。

例如:

SELECT 
event.type as type,
IF(type = 'birthday', birthday.birthday_id, NULL) as birthday,
IF(type = 'graduation', graduation.graduation_id, NULL) as graduation,
IF(type = 'wedding', wedding.wedding_id, NULL) as wedding
FROM event
LEFT OUTER JOIN birthday ON birthday_id = event.target_id
LEFT OUTER JOIN graduation ON graduation_id = event.target_id
LEFT OUTER JOIN wedding ON wedding_id = event.target_id

没有经过测试,但希望这可以帮助您澄清疑虑。


谢谢J,和Sebas的答案一样,他比你快了一点。 - Yarin

0

Sebas的答案是正确的,但不需要为每个前面的连接检查IS NULL条件,您可以使用基于列值的方法使其更有效。我已经测试过了,它可以正常工作。

SELECT 
    E.type AS type,
    IF(E.type = 'birthday', B.id, NULL) AS birthday_id,
    IF(E.type = 'graduation', G.id, NULL) AS graduation_id,
    IF(E.type = 'wedding', W.id, NULL) AS wedding_id
FROM event E 
    LEFT OUTER JOIN birthday B ON E.type = 'birthday' AND E.target_id = B.id
    LEFT OUTER JOIN graduation G ON E.type = 'graduation' AND E.target_id = G.id
    LEFT OUTER JOIN wedding W ON E.type = 'wedding' AND E.target_id = W.id 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接