2012-01-10 11 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は、一意IDは、投稿の列を識別意味します。 アクション= 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」のためのものです。 一意IDの代わりに、このだったかのように、クエリでそれだけだろうので、私は何を返すようにしたいことは、PostIDです:あなたの状態= 0フィルタはコメントへの接続を制限した場合

1 
2 
1 
1 
1 

答えて

1

、その後、内部結合投稿には結果を除外することができ、テストには左にも参加するようにしてください。

ORDER BY句(ORDER BY P.StateまたはN.Stateのいずれか)に接頭辞を付ける必要があります。

あなたはN.idとの誤差を持っている理由は、idがすでにN.で選択されていることである*

あなたは、複数の状態に対処するために列挙型を使用する方がよいでしょう。これは、同じパフォーマンス(すなわち、N.action = 'add'、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

ああ、申し訳ありませんが実際に私が間違って引用符を入れていませんでしたが、それは実際には動作するように思われます..そして私は今それが実際には以前のように動作していたことを認識していますが、詳細に注意を払う必要はありません。問題は解決されましたが、私はまだこのコードを整理するための助けが必要です。可能であれば、かなり面倒です。 –

関連する問題