简体   繁体   English

MySQL Left Join是否从左表返回所有数据?

[英]MySQL Left Join return all data from left table?

I have two tables. 我有两张桌子。 I need to return a row from the left table even for options that are not in the right table. 我需要从左表返回一行,即使对于不在右表中的选项也是如此。

Just for the example I have setup two sample tables. 仅作为示例,我设置了两个示例表。 Here is the code to create tables & populate sample data: 这是创建表和填充示例数据的代码:

CREATE TABLE `names` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `optionid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;

/*Data for the table `names` */

insert  into `names`(`id`,`name`,`optionid`) values (1,'name1',1),(2,'name2',2),(3,'name3',3),(4,'name4',4);

CREATE TABLE `options` (
  `tableid` int(11) NOT NULL AUTO_INCREMENT,
  `description` varchar(30) DEFAULT NULL,
  `optionid` int(11) DEFAULT NULL,
  PRIMARY KEY (`tableid`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;

/*Data for the table `options` */

insert  into `options`(`tableid`,`description`,`optionid`) values (1,'option1',1),(2,'option2',1),(3,'option3',1),(4,'option1',2),(5,'option2',2),(6,'option1',3),(7,'option',3);

OK so I can left join which will return all rows from left and put NULL's on the right for any data not in the right table which is almost there. 好的,所以我可以左联接,它将从左返回所有行,并将NULL放在右边,以存储不在右表中的任何数据。

Now if there is a matching value in the right table it only returns values that have data in the right table. 现在,如果右表中有匹配的值,则它仅返回右表中具有数据的值。 now I need to return what I would class as the master record and then all the options from the right. 现在,我需要返回要归类为主记录的内容,然后返回右侧的所有选项。

So if I run: 因此,如果我运行:

SELECT
      `names`.`id`
    , `names`.`name`
    , `names`.`optionid`
    , `options`.`description`
    , `options`.`optionid`

FROM
    `test`.`names`
    LEFT JOIN `test`.`options` 
        ON (`names`.`optionid` = `options`.`optionid`);

This returns: 返回:

   id   name    optionid    description optionid
1   name1   1           option1          1
1   name1   1           option2          1
1   name1   1           option3          1
2   name2   2           option1          2
2   name2   2           option2          2
3   name3   3           option1          3
3   name3   3           option           3
4   name4   4           NULL            NULL

This is exactly what I would expect but not what I want. 这正是我所期望的,但不是我想要的。

The Last row, ID 4 returns data with nulls because there is no data in the right table now I need to return this row for ID 1, 2 & 3 even though there is data in the right table, so even if there is data you still get the first record returned with NULL's from the left. ID 4的最后一行返回的数据为空,因为正确的表中没有数据,即使正确的表中有数据,我也需要返回ID 1、2和3的这一行,所以即使有数据仍然从左边获得第一个返回为NULL的记录。

I know this doesn't make a whole lot of sense but for the project I am working on if there are related options the first record is classed as a Master/Shell record and the options are looped though in PHP however for the API I need to handle this in SQL which means returning the extra Shell record. 我知道这没有什么意义,但是对于我正在研究的项目,如果有相关选项,则将第一条记录归类为“主/壳”记录,并且这些选项虽然在PHP中循环,但是对于API,我需要在SQL中处理这意味着返回额外的Shell记录。

So what I would like the results to be are: 所以我想要的结果是:

   id   name    optionid    description optionid
1   name1   1           NULL             NULL
1   name1   1           option1          1
1   name1   1           option2          1
1   name1   1           option3          1
2   name1   1           NULL             NULL
2   name2   2           option1          2
2   name2   2           option2          2
3   name1   1           NULL             NULL
3   name3   3           option1          3
3   name3   3           option           3
4   name4   4           NULL            NULL

Not sure if this is possibel but any feedback would be appreciated. 不知道这是否可行,但是任何反馈将不胜感激。 Thanks in advance. 提前致谢。

Can't think of an elegant way of doing it (hopefully someone else will suggest something), but possible to do it using a UNION:- 想不出一种优雅的方法(希望有人会提出建议),但是可以使用UNION做到这一点:

SELECT `names`.`id`, `names`.`name`, `names`.`optionid`, `options`.`description`, `options`.`optionid`
FROM `test`.`names`
LEFT JOIN `test`.`options` 
ON (`names`.`optionid` = `options`.`optionid`)
UNION
SELECT `names`.`id`, `names`.`name`, `names`.`optionid`, NULL, NULL
FROM `test`.`names`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM