Объединение разных таблиц на основе значения столбца - программирование
Подтвердить что ты не робот

Объединение разных таблиц на основе значения столбца

У меня есть таблица под названием notifications:

CREATE TABLE `notifications` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `type` varchar(20) NOT NULL DEFAULT '',
  `parent_id` int(11) DEFAULT NULL,
  `parent_type` varchar(15) DEFAULT NULL,
  `type_id` int(11) DEFAULT NULL,
  `etc` NULL
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;

Каждый notification связан с другой таблицей, значение поля parent_type указывает имя таблицы, в которой я хочу * join таблицу с. Все целевые таблицы имеют несколько одинаковых столбцов:

CREATE TABLE `tablename` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `is_visible` tinyint(1) NOT NULL,      
  `etc` NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

В настоящее время я использую этот запрос для выбора notifcations, что их связанная строка в целевой таблице существует, а поле is_visible 1:

SELECT n.id, 
FROM notifications n 
LEFT JOIN books b ON n.parent_id = b.id AND n.parent_type = 'book' AND b.is_visible = 1
LEFT JOIN interviews i ON n.parent_id = i.id AND n.parent_type = 'interview' AND i.is_visible = 1
LEFT JOIN other tables...
WHERE n.user_id = 1
GROUP BY n.id

Но так как это LEFT JOIN, он возвращает уведомление, если оно соответствует любой таблице или нет, как я могу его переписать, чтобы он не возвращал уведомления, которые не соответствуют ни одной строке в целевой таблице? Я также безуспешно пробовал инструкцию CASE.

4b9b3361

Ответ 1

Я не уверен на 100%, что синтаксис прав, и у меня нет возможности проверить его прямо сейчас, но идея должна быть ясной.

SELECT DISTINCT n.id 
FROM notifications n 
JOIN (
     (SELECT b.id, 'book' AS type FROM books b WHERE b.is_visible = 1)
  UNION
     (SELECT i.id, 'interview' AS type FROM interviews i WHERE i.is_visible = 1)
) ids ON n.parent_id = ids.id AND n.parent_type = ids.type
WHERE n.user_id = 1