2012-01-20 10 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 подпишитесь на уведомление_база 5 и последнее время уведомления x)

После этого другой пользователь коснется этого элемента notification_base. (например, комментарий статуса или как фотография) Это действие записывается в таблице notification_action (пользователь 5 делает действие «как» 12/02/2011).

Что я хочу, это получить элементы notification_base от пользователя подписка, если последнее notifiytime меньше, чем действие уведомления, а затем присоединиться к ним с уведомлением_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 ; 

результат почти то, что я хочу, например

пользователь х сделал «действие» на вашем объекте, который имеет «тип» и object_id в момент времени т

, но я также хочу, чтобы присоединиться на object_id зависит от типа. Так что я действительно могу узнать, к какому объекту прикоснулся. Но поскольку вы можете видеть, что тип является динамическим, если type = post object id ссылается на post_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

ok теперь я получил ошибку «Используемые операторы SELECT имеют различное количество столбцов», потому что структура таблицы отличается друг от друга, и мне также нужно получить разные данные из каждой таблицы. –

ответ

4

вы не можете условно создавать соединения по таблицам. Лучший способ сделать это - использовать LEFT JOIN и использовать CASE в своем заявлении SELECT. Вы должны указать общие столбцы, которые вы хотите показать,

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 приветствую! –

Смежные вопросы