【问题标题】:Joining different tables based on column value根据列值连接不同的表
【发布时间】:2013-09-01 05:42:11
【问题描述】:

我有一张桌子叫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

标签: mysql sql


【解决方案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

【讨论】:

  • 使用JOINUNION 可以解决问题。非常感谢。
  • 谢谢!这对我有帮助!
  • 注意:此语法仅适用于 MySQL。不适用于 SQLite。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-04
  • 1970-01-01
  • 2019-12-18
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
相关资源
最近更新 更多