基于列值连接不同的数据表

27

我有一张名为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;

目前我正在使用此查询来选择存在于目标表中其关联行并且它们的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语句,但没有成功。


你尝试过不用 LEFT,而是使用 JOIN 吗? - user1646111
1个回答

42

我并不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

2
дҪҝз”ЁJOINе’ҢUNIONеҸҜд»Ҙи§ЈеҶій—®йўҳгҖӮйқһеёёж„ҹи°ўгҖӮ - Ram
谢谢!这对我很有帮助! - Стас Пишевский
注意:此语法仅适用于MySQL,不适用于SQLite。 - Ricky Han

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接