简化MYSQL查询和修复

时间:2012-01-10 00:22:52

标签: php mysql database join simplify

我一直试图让这个复杂的 MYSQL查询在过去几天完全正常工作,当然因为它有很多方面影响它很难肯定知道它是100%正常工作,我对更复杂的MYSQL查询并不是很好。我现在的这个查询也非常混乱,所以它返回的数据有点分散,我不确定如何解决这个问题。我已经阅读了MYSQL Join和所有内容,我有点理解它,但我不确定在我的情况下使用哪种,以及如何正确使用它们。

这是我当前的查询,它应该正常工作。 (我认为,只需要清理,所以我不必有多余的值)

$notificationsq = mysql_query("SELECT
N.*,
N.fromID,
N.date,
N.id AS ID,   //I have to do this because if I don't it doesn't return anything, 
              ///I guess because it joins 3 tables with the id column. not sure 
              ///how to call the correct data.
MIN(N.state) AS State,
MAX(N.date) AS newDate,
P.*,
C.*,
P.id AS uniqueID
FROM notifications N
LEFT JOIN comments C ON N.action = 2 AND N.uniqueID = C.id AND C.state=0
LEFT JOIN posts P ON N.action = 1 AND P.id = N.uniqueID 
OR N.action = 2 AND P.id = C.postID
WHERE N.userID = '$session'
AND (N.action = 1 AND N.state IN (0, 1) OR N.action = 2)
AND P.state = 0

GROUP BY P.id
ORDER BY
State ASC,  
newDate DESC


 ") or die(mysql_error());

我的表结构:

Table: notifications

id  UserID  FromID  UniqueID    Action  State   Read_Date   Date
1   1       2       1           1       0       0           1325993600
2   1       6       2           1       0       0           1325993615
3   1       2       1           2       0       0           1325993622
4   1       6       2           2       0       0           1325993661
5   2       6       2           2       0       0           1325993661

Action = 1表示UniqueID标识帖子中的列; Action = 2表示UniqueID标识注释中的列。

Table: posts

id  ToID    FromID  Post        State   Date
1   1       2       Hey         0       1325993600
2   1       6       okay yeah   0       1325993615

Table: comments

ID  PostID  FromID  Comment     State   Date
1   1       2       lol         0       1325993622
2   1       6       ohh         0       1325993661

因此,在Notifications表中,action为2,UniqueID是针对Comments表中的'id'。 我想要返回的是PostID,因此在查询中它就像是UniqueID就是这样:

1
2
1
1
1

1 个答案:

答案 0 :(得分:1)

如果你的州= 0过滤器限制了与评论的连接,那么帖子上的内部联接可以过滤掉结果,尝试将左联接也用于测试。

你的ORDER BY子句应该有一个前缀(ORDER BY P.State或N.State)。

您在使用N.id时遇到错误的原因是已经使用N选择了ID。*

您最好使用ENUM类型来处理多个状态。这导致更具可读性的SQL具有相同的性能(即N.action ='add',而不是2)

避免任何选择*,它容易出错并且性能不如手动替代。

就清理而言,我发现使用干净的空白和名称更容易阅读:

SELECT notifications.*
     , notifications.fromID
     , notifications.date
     , MIN(notifications.state) AS State
     , MAX(notifications.date) AS newDate
     , posts.*
     , comments.*
     , posts.id AS uniqueID
FROM notifications
LEFT JOIN comments ON notifications.action = 2
                  AND notifications.uniqueID = C.id
                  AND comments.state = 0
LEFT JOIN posts ON (notifications.action = 1 AND posts.id = notifications.uniqueID)
                OR (notifications.action = 2 AND posts.id = comments.postID)
WHERE notifications.userID = '$session'
  AND (notifications.action = 1 AND notifications.state IN (0, 1) OR notifications.action = 2)
  AND posts.state = 0
GROUP BY posts.id
ORDER BY notifications.State ASC
       , newDate DESC