在`INNER JOIN`中使用`as`列 - “ON”

时间:2015-06-12 14:30:27

标签: mysql

我正在尝试使用别名引用的计算列作为JOIN表达式。

这是查询;问题出在idMem

SELECT IF(c.memGet=$idMemOnline,c.memSend,c.memGet) as idMem
FROM chat c
LEFT JOIN members m
ON (m.id = idMem)     // here the problem
WHERE (c.memSend=$idMemOnline || c.memGet=$idMemOnline) && c.isLast=true 

有没有办法将计算字段用作JOIN键?

2 个答案:

答案 0 :(得分:0)

您无法在ON子句中使用别名。请改用IF功能:

SELECT IF(c.memGet=$idMemOnline,c.memSend,c.memGet) as idMem
FROM chat c
LEFT JOIN members m
ON (m.id = IF(c.memGet=$idMemOnline,c.memSend,c.memGet)) 
WHERE (c.memSend=$idMemOnline || c.memGet=$idMemOnline) && c.isLast=true 

答案 1 :(得分:0)

您想要获取会员的所有最后聊天消息,他们是发件人以及他是收件人的那些人。你不想在JOIN子句中有一个IF,即使MySQL经常可以优化它。

SELECT IF (c.memGet=$idMemOnline, c.memSend, c.memGet) as idMem
FROM chat c LEFT JOIN members m
ON (m.id = c.memSend OR m.id = c.memGet)
WHERE (c.memSend=$idMemOnline OR c.memGet=$idMemOnline) AND c.isLast=true 

但也许更好的方法是独立选择两个组,这样可以更好地使用索引,例如,如果您有isLastmemSend的索引,并且 isLastmemGet上的另一个索引:

SELECT c.memSend as idMem
    FROM chat AS c WHERE (c.memGet=$idMemOnline AND c.isLast=true)
UNION
SELECT c.memGet as idMem
    FROM chat AS c WHERE (c.memSend=$idMemOnline AND c.isLast=true);

或者,如果您还希望成员提供信息,

SELECT m.name, idMem FROM (
    SELECT c.memSend as idMem
        FROM chat AS c WHERE (c.memGet=$idMemOnline AND c.isLast=true)
    UNION
    SELECT c.memGet as idMem
        FROM chat AS c WHERE (c.memSend=$idMemOnline AND c.isLast=true)
) AS c2 JOIN members AS m ON (id = $idMemOnline);

-- (or on (id = idMem) if you wanted data on the other member).

在最后一种情况下,您可能还需要members.id上的索引。

Here一个工作小提琴。