Mysql从多对多获取相关表的所有记录

时间:2018-06-28 18:23:35

标签: mysql

我有3个表,我需要列出所有选项以及所有具有或不具有选项的帖子,实际上我已经做到了,但是我只显示具有选项但没有选项的帖子选项不会在列表中显示它们。

sqlfiddle中的示例: http://sqlfiddle.com/#!9/8d27dd/1

如果您查看列表,则将ID 1的帖子分配给3个选项,并向我显示第四个行值为null,而ID 2的帖子则分配给我一个选项,但是我需要显示所有表[post_options]中所有现有选项的值为null的其他行。

表格:

  

tabla [帖子] -保存所有主要帖子

     

tabla [post_options] -保存帖子的所有选项

     

tabla [post_has_options] -保存所有具有选项的帖子

表格代码:

CREATE TABLE `post` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `id_post_type` tinyint(3) unsigned NOT NULL,
  `title` varchar(255) NOT NULL,
  `create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `modified_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `FK_title_UNIQUE` (`title`) USING BTREE,
  KEY `FK_post_post_types` (`id_post_type`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

INSERT INTO `post` VALUES ('1', '1', 'Title 1', '2018-01-27 14:58:24', '2018-01-27 23:10:00');
INSERT INTO `post` VALUES ('2', '1', 'Title 2', '2018-01-27 14:58:24', '2018-01-27 23:10:00');
INSERT INTO `post` VALUES ('3', '1', 'Title 3', '2018-01-27 14:58:24', '2018-01-27 23:10:00');
INSERT INTO `post` VALUES ('4', '1', 'Title 4', '2018-01-27 14:58:24', '2018-01-27 23:10:00');

CREATE TABLE `post_has_options` (
  `id_post` int(10) unsigned NOT NULL,
  `id_post_work_type` tinyint(3) unsigned NOT NULL,
  `create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `modified_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id_post`,`id_post_work_type`),
  KEY `id_post_work_type` (`id_post_work_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `post_has_options` VALUES ('1', '1', '2018-01-27 22:00:51', '2018-01-27 22:00:51');
INSERT INTO `post_has_options` VALUES ('1', '2', '2018-01-27 22:00:54', '2018-01-27 22:00:54');
INSERT INTO `post_has_options` VALUES ('1', '3', '2018-01-27 22:00:58', '2018-01-27 22:00:58');
INSERT INTO `post_has_options` VALUES ('2', '2', '2018-01-27 22:45:19', '2018-01-27 22:45:19');

CREATE TABLE `post_options` (
  `id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `modified_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `FK_name_UNIQUE` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

INSERT INTO `post_options` VALUES ('1', 'Work type 1', '2018-01-27 14:59:30', '2018-01-27 14:59:30');
INSERT INTO `post_options` VALUES ('2', 'Work type 2', '2018-01-27 14:59:30', '2018-01-27 14:59:30');
INSERT INTO `post_options` VALUES ('3', 'Work type 3', '2018-01-27 14:59:30', '2018-01-27 14:59:30');
INSERT INTO `post_options` VALUES ('4', 'Work type 4', '2018-01-27 14:59:30', '2018-01-27 14:59:30');

查询:

SELECT *
FROM post_options P
LEFT JOIN post_has_options PHO ON PHO.id_post_work_type = P.id

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我想这就是你想要的:

SELECT 
    *
FROM 
    post AS p
LEFT OUTER JOIN 
    post_has_options AS pho
    ON 
    p.id = pho.id_post
LEFT OUTER JOIN
    post_options AS po
    ON
    po.id = pho.id_post_work_type

如果没有,请告诉我您需要什么不同,我将编辑答案。如果这是您需要的,请记住标记为已回答,这样人们就会知道您不再需要帮助。