2012-01-20 28 views
6

Genel bir bildirim sistemi uygulamaya çalışıyorum .. Böyle bir veri yapısına sahibim; Yani temel senaryomysql koşullu birleşim bir sütuna bağlıdır

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

, kullanıcı posta yoluyla bir durum bildirim taban öğesi oluşturabilir veya bu durumda statüsünde bir fotoğraf vb (yükleyebilir, fotoğraf notification_base tablodaki alan yazın atıfta ve Object_id Post_id veya photo_id olduğu Ardından kullanıcı bu notification_base öğesi .. (kullanıcı 3 5 notification_base abone olmak ve son kez x bildirmek) o başka bir kullanıcı dokunma bu notification_base öğesi sonra

için abone) türüne bağlıdır. (örneğin bir durumu veya bir fotoğrafı beğenin gibi) Bu eylem, bildirim_adı tablosunda (kullanıcı 5, eylemi 12/02/2011 tarihinde 'like' gibi) kaydeder.

İstediğim, bildirim_base öğelerini kullanıcıdan alır. bir bildirim eyleminden daha küçükse, bir bildirim eyleminden daha küçükse, abonelik size bildirilir. Bu sql ile başarabilirim;

Kullanıcı kimliği 3 için;

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 ; 

sonuç

kullanıcı x 'türü' vardır senin nesne üzerinde 'eylemi' yaptı ve t zamanında

de object örneğin, hemen hemen istediğim budur ama aynı zamanda üzerinde katılmak istiyorum object_id türüne bağlıdır .. Bu yüzden aslında hangi nesnenin dokunduğunu öğrenebilirim .. Fakat türün dinamik olduğunu görebildiğiniz gibi, type = post object kimliği post tablosunda post tablosuna başvurursa, type = fotoğraf nesnesi kimliği fotoğraf tablosunda photo_id ve etc'yi ifade ediyorsa ..

Böyle bir şey yapmaya çalışıyorum ama öyle olsun bana sözdizimi hatası;

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; 

Bunun doğru olmadığını biliyoruz, bu koşullu oluşturamıyor

+0

http://stackoverflow.com/questions/1255492/conditional-join-in-mysql bakın, göstermek istediğiniz ortak sütunları belirtmek olmalıdır ve sol birleştirme stratejisi işe yarayacaktı, ancak çok sayıda tablonuz varsa çok fazla katılma gerektirecektir. – dash

+0

tamam şimdi "Kullanılan SELECT ifadelerinin farklı sayıda sütunları var" hatası aldım. Bu tabloyu birbirinden farklı yapıyorum ve ayrıca her tablodan farklı veriler almam gerekiyor. –

cevap

4

tablolar arasında katılır sözde kod gibi. Yapmanın en iyi yolu, LEFT JOIN'u kullanmak ve SELECT ifadenizde CASE'u kullanmaktır. Örneğin, birlikte sendika birçok sorguları mümkün olabilir - Sen

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

, bulduğum çözüm buydu, cevabınız için teşekkürler, soruyu güncellemeyi tamamen unutuyorum. –

+0

size yardımcı olduğunuz için mutluyuz: D –