2012-05-18 31 views
1

我有一个用户消息表,其中存储了在站点上的两个用户之间发送的所有消息。你可以使用大小写来指定在MySQL中使用的连接吗?

每封邮件有sourceUserIdfriendId,这些是发件人和收件人。

每个用户消息收件箱都列出所有发送和接收的消息,每条消息显示哪个用户已发送或接收该消息。

问题

由于我们列出发送和接收的用户,一些列是围绕着错误的方式,例如,如果当前用户的用户ID为1

  • 发送的消息将有1
  • 一个sourceUserId收到的邮件将有1

如果我试图和d。friendId o带有一个查询的整个收件箱,那么我必须在sourceUserIdfriendId上进行两次连接,因为我无法分辨哪个是当前登录的用户。

我已经知道当前登录的用户的用户名,所以当只需要一个连接时有两个连接似乎不正确?

我想知道是否有可能使用某种情况下在一个MySQL查询,有效地实现以下,并减少了每次要查找的数据量..

SELECT um.message, UNIX_TIMESTAMP(um.time), um.read, user.username 
FROM usermessages um 
    CASE 
     WHEN um.friendId = 1 
      INNER JOIN user ON um.sourceUserId = user.id 
     WHEN um.sourceUserId = 1   
      INNER JOIN user ON um.friendId = user.id 
    END 
WHERE (um.friendId = 1 OR um.sourceUserId = 1) 

回答

2

你需要使用CASEON条款,而不是

SELECT um.message, UNIX_TIMESTAMP(um.time), um.read, user.username 
FROM usermessages um 
INNER JOIN user ON 
    CASE 
     WHEN um.friendId = 1 THEN um.sourceUserId 
          ELSE um.friendId 
    END = user.id 
WHERE (um.friendId = 1 OR um.sourceUserId = 1) 

(或移动比较= user.idCASE如果你更好地喜欢它)

+0

谢谢,你们有这么多有用的查询优化知识! – Dan

1

另一种方法,而不是使用情况下,做到这一点的布尔方式:

SELECT um.message, UNIX_TIMESTAMP(um.time), um.read, user.username 
FROM usermessages um 
INNER JOIN user ON 
    (um.friendId = 1 AND um.sourceUserId = user.id) 
    OR 
    um.friendId = user.id 
WHERE (um.friendId = 1 OR um.sourceUserId = 1) 
+0

哪一个会更好?有什么不利的情况下呢? – Dan

+0

@ Silver89:不。两种解决方案都很慢并且无法优化:-) – zerkms

+0

我总是用这种方式写查询;此外,非数据库编程语言并不完全具有CASE WHEN,所有操作都是布尔型的。如果这比以前的情况更快,就不会进行分析。 –

相关问题