2012-01-20 15 views
6

私は一般的な通知システムを実装しようとしています。私はこのようなデータ構造を持っています。mysql条件付き結合は列に依存します

notification_base:id,type,object 
notificiation_sub:id,user_id,not_base_id,lastNotifyTime 
notification_action:id,user_id,not_base_id,action,creationDate 

だから基本的なシナリオは、ユーザがポストによってステータスを通知基本アイテムを作成し、または写真等をアップロードし、(この場合の状態で、写真はnotification_baseテーブルとのobject_idのフィールドを入力する意味post_idの又はphoto_idありますタイプに依存) ユーザはこのnotification_baseアイテムを購読します。(ユーザ3 subscribe notification_base 5と最後の通知時間x)

その後、別のユーザがこのnotification_baseアイテムに触れます。 (例えば、ステータスや写真のようにコメントする) このアクションはnotification_actionテーブルに記録されます(ユーザ5は12/02/2011で「like」のようになります)。

ユーザからnotification_baseアイテムを取得します。最後にnotifiytimeが通知アクションより小さい場合は、サブスクリプションをnotification_actionと結合してください。 このSQLで成功することができます。

ユーザID 3の場合。

select * from notification_action 
       inner join notification_base on notification_action.not_base_id = notification_base.id 
       inner join notification_sub on notification_action.not_base_id = notification_sub.not_base_id 
       where notification_sub.user_id = 3 and notification_sub.lastShowDate < notification_action.creationDate ; 

結果は

ユーザーx「はタイプ」があり、あなたのオブジェクトに「アクション」を行なったし、時間t

でOBJECT_ID例えば、ほとんど私が欲しいものですが、私はまた、上に参加したいですobject_idはタイプに依存するので実際にどのオブジェクトに触れているかを知ることができます。しかし、タイプが動的であるように、タイプ=投稿オブジェクトidは投稿テーブルのpost_idを参照し、タイプ=写真オブジェクトIDは写真テーブルなどのphoto_idを参照します。 ..

私はこれのような何かをしようとするが、そうだ私の構文エラー。

SELECT * 
FROM notification_action 
INNER JOIN notification_base 
    ON notification_action.not_base_id = notification_base.id 
INNER JOIN notification_sub 
    ON notification_action.not_base_id = notification_sub.not_base_id CASE notification_base.type 
      WHEN 'photo' 
       THEN (
         INNER JOIN photo 
          ON photo.id = notification_base.object_id 
         ) 
      ELSE (
        INNER JOIN post 
         ON post.id = notification_base.object_id 
        ) 
      END 
WHERE notification_sub.user_id = 3 
    AND notification_sub.lastShowDate < notification_action.creationDate; 

私はそれが正しいではないことを知っているが、それはあなたが条件付きで作成することはできません

+0

http://stackoverflow.com/questions/1255492/conditional-join-in-mysqlを参照してください、あなたが表示したい共通の列を指定している必要があります、そして左の結合方法は機能しますが、テーブルがたくさんある場合は、多くの結合が必要になります。 – dash

+0

今、私は "使用されたSELECTステートメントは異なる数の列を持っています"というエラーを受けました。なぜなら、テーブル構造はお互いに異なっていて、各テーブルから別のデータを取得する必要があるからです。 –

答えて

4

は、テーブル全体で加入擬似コードのようなものです。最良の方法はLEFT JOINを使用し、SELECTステートメントにCASEを使用することです。あなたは、例えば、一緒に組合多くのクエリにできる可能性があります - あなたは

SELECT *, 
     (CASE notification_base.type 
      WHEN 'photo' 
      THEN photo.columnName1 
      ELSE post.ColumnName1 
     END) as ColumnName1, 
     (CASE notification_base.type 
      WHEN 'photo' 
      THEN photo.columnName2 
      ELSE post.ColumnName2 
     END) as ColumnName2 
FROM notification_action 
    INNER JOIN notification_base 
     ON notification_action.not_base_id = notification_base.id 
    INNER JOIN notification_sub 
     ON notification_action.not_base_id = notification_sub.not_base_id 
    INNER JOIN photo 
     ON photo.id = notification_base.object_id 
    INNER JOIN post 
     ON post.id = notification_base.object_id 
WHERE notification_sub.user_id = 3 
    AND notification_sub.lastShowDate < notification_action.creationDate; 
+0

それは私が思いついた解決策でした、答えのおかげで、私は完全に質問を更新することを忘れています。 –

+0

あなたを助けてくれることを嬉しく思っています。Dあなたは大歓迎です! –