我一直在尝试使这种复杂的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


动作= 1表示UniqueID标识帖子中的一列;
动作= 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


因此,在actions为2的Notifications表中,UniqueID是Comments表中的“ id”。
我要返回的是PostID,因此在查询中就好像UniqueID是这样:

1
2
1
1
1

最佳答案

如果您的状态= 0过滤器将连接限制到注释,则帖子上的内部联接可能会过滤掉结果,并尝试使该联接成为左联接以进行测试。

您应该在ORDER BY子句上有一个前缀(ORDER BY P.State或N.State)。

您在使用N.id时出错的原因是该ID已被N. *选择。

最好使用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

关于php - 简化MYSQL查询并修复,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8797054/

10-12 16:40
查看更多