我一直试图让这个复杂的 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
答案 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