упрощение запроса MYSQL и исправление - PullRequest
0 голосов
/ 10 января 2012

Я пытался заставить этот сложный 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 идентифицирует столбецв сообщениях;Действие = 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

Таким образом, в таблице уведомлений, где действие равно 2, уникальные идентификаторы для идентификатора в таблице комментариев.То, что я хочу вернуть, это PostID, поэтому в запросе это будет так, как если бы это был UniqueID:

1
2
1
1
1

1 Ответ

1 голос
/ 10 января 2012

Если ваш фильтр состояния = 0 ограничивает подключение к комментариям, то внутреннее объединение в сообщениях может отфильтровать результат, попробуйте сделать это также левым объединением для проверки.

У вас должен бытьпрефикс в предложении ORDER BY (ORDER BY P.State или N.State).

Причина возникновения ошибки с N.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
...