2012-01-10 2 views
0

나는 이걸 MYSQL 쿼리가 지난 며칠 동안 정확하게 작동하도록 노력했지만, 물론 그 효과가 너무 많아서 분명히 어렵다. 그것은 100 % 제대로 작동하고, 나는 더 복잡한 MySQL 쿼리에 전혀 익숙하지 않다는 것을 알아라. 또한 내가 지금 가지고있는이 쿼리는 상당히 엉망입니다. 따라서 반환하는 데이터는 조금 흩어져 있습니다.이 문제를 해결하는 방법을 정확히 모르겠습니다. MYSQL Join을 통해 읽었으며, 모든 것을 이해하고 있지만, 필자는 어떤 경우에 사용할 것인지, 어떻게 적절하게 사용하는지 잘 모르겠습니다.MYSQL 쿼리를 단순화하고 수정하기

다음은 현재 수행해야하는 현재 쿼리입니다. (단지 내가 중복 값을 가질 필요가 없습니다, 생각, 청소 필요가)

$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 

따라서 조치가 2 인 알림 테이블에서 고유 ID는 설명 테이블의 'id'에 대한 것입니다. 당신의 국가 = 0 필터는 다음 내부 조인, 의견에 대한 연결을 제한하는 경우

1 
2 
1 
1 
1 

답변

1

다음을 UniqueID이 아닌 것처럼 그냥 것 쿼리 있도록 은 내가 반환하고자하는의 PostID입니다 게시물에 결과를 걸러 낼 수 있습니다, 테스트를 왼쪽으로 조인하게하십시오.

ORDER BY 절 (ORDER BY P.State 또는 N.State)에 접두사가 있어야합니다.

당신이 N.id에 오류가 발생하는 이유는 ID가 이미 N. *

여러 상태를 처리하는 ENUM 타입을 사용하는 것이 더 낫다으로 선택되어 있습니다. 이로 인해 동일한 성능 (예 : 2 대신 N.action = 'add')이 더 읽기 쉬운 SQL이됩니다.

select *를 피하십시오. 오류가 발생하기 쉽고 성능이 수동 대안보다 좋지 않습니다.

이 지금까지 청소로, 나는 훨씬 쉽게 청소 공백 및 이름을 읽을 찾을 : 만들기

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 
+0

그것을 남아있는 차이가 나타나지 않습니다 가입 및 추가 "C.state = 0 "여전히 mysql 오류를 반환 –

+0

어떤 mysql 오류? – amccausl

+0

오, 죄송합니다. 실제로 제가 속한 곳이 아닌 곳에서 실수로 인용문을 넣었습니다. 실제로는 작동해야하는 것으로 보입니다. 그리고 실제로는 이전에 어떻게 작동했는지를 깨닫고 있습니다. 세부 사항에주의를 기울이지 않아도 .... 문제가 해결되었지만 가능한 한이 코드를 정리하는 데 도움이 필요하다. –