MySQL用where子句

时间:2018-10-01 02:42:36

标签: mysql sql outer-join

我正在尝试使用以下MySQL查询:

SELECT *
FROM top_lines t
LEFT OUTER JOIN last_24_topline AS l ON l.`member_no` = t.`member_no` 
    AND l.`mfg` = t.`line_no`
WHERE l.account_no = 32049 OR l.account_no IS NULL

但是,这没有返回任何行,因为last_24_topline中没有account_no行匹配。从我所了解和阅读的所有内容来看,即使在last_24_topline中没有行匹配,该查询仍应返回top_lines中的所有行,因为我正在检查值或null,但事实并非如此。 MySQL(5.7.2)中是否有任何选项或设置会导致此行为? 仅作为参考,此查询可按预期工作:

SELECT *
FROM top_lines t
LEFT OUTER JOIN last_24_topline l ON l.`member_no` = t.`member_no` 
    AND l.`mfg` = t.`line_no`
    AND l.`account_no` = 32049

但是,由于我正在使用实体框架,因此我无法使用此构造,并且您只能将列而不是值传递给联接


CREATE TABLE `last_24_topline` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `member_no` varchar(30) NOT NULL,
  `branch_no` int(11) DEFAULT NULL,
  `employee_no` varchar(25) DEFAULT NULL,
  `account_no` varchar(25) DEFAULT NULL,
  `salesperson_name` varchar(255) DEFAULT NULL,
  `customer_name` varchar(255) DEFAULT NULL,
  `mfg` varchar(5) DEFAULT NULL,
  `mfg_description` varchar(255) DEFAULT NULL,
  `last_three` decimal(10,2) DEFAULT '0.00',
  `last_twelve` decimal(10,2) DEFAULT '0.00',
  `ly_last_three` decimal(10,2) DEFAULT '0.00',
  `ly_last_twelve` decimal(10,2) DEFAULT '0.00',
  PRIMARY KEY (`id`),
  KEY `ix_branch_no` (`branch_no`),
  KEY `ix_employee_no` (`employee_no`),
  KEY `ix_member_line_account` (`member_no`,`mfg`,`account_no`),
  KEY `ix_member_line` (`member_no`,`mfg`),
  KEY `ix_account_no` (`account_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

CREATE TABLE `top_lines` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `member_no` varchar(30) NOT NULL,
  `line_no` varchar(5) NOT NULL,
  `line_description` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `ix_line_no` (`member_no`,`line_no`)
) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=latin1

insert  into `top_lines`(`id`,`member_no`,`line_no`,`line_description`) values (1,'520','772','FED ROTOR/DRUM');
insert  into `top_lines`(`id`,`member_no`,`line_no`,`line_description`) values (2,'520','952','FED SST CERAMIC');
insert  into `top_lines`(`id`,`member_no`,`line_no`,`line_description`) values (3,'520','954','FED SST FRICTION');
insert  into `top_lines`(`id`,`member_no`,`line_no`,`line_description`) values (4,'520','162','EVS FRICTION');

INSERT INTO `last_24_topline` (`id`, `member_no`, `branch_no`, `employee_no`, `account_no`, `salesperson_name`, `customer_name`, `mfg`, `mfg_description`, `last_three`, `last_twelve`, `ly_last_three`, `ly_last_twelve`) VALUES('1','520','0','10856','463854','FORD, JAMES,','JIFFY LUBE','459','FEDERATED AIR FILTER','0.00','15.21','0.00','0.00');
INSERT INTO `last_24_topline` (`id`, `member_no`, `branch_no`, `employee_no`, `account_no`, `salesperson_name`, `customer_name`, `mfg`, `mfg_description`, `last_three`, `last_twelve`, `ly_last_three`, `ly_last_twelve`) VALUES('2','520','0','10856','463854','FORD, JAMES,','JIFFY LUBE','460','FILTERS','0.00','0.00','0.00','16.48');
INSERT INTO `last_24_topline` (`id`, `member_no`, `branch_no`, `employee_no`, `account_no`, `salesperson_name`, `customer_name`, `mfg`, `mfg_description`, `last_three`, `last_twelve`, `ly_last_three`, `ly_last_twelve`) VALUES('3','520','0','10856','463854','FORD, JAMES,','JIFFY LUBE','863','SMP T SERIES','0.00','0.00','0.00','50.67');

即使在last_24_topline中没有数据匹配的情况下,我也希望第一个查询产生一个结果集,其中包含top_lines中的所有行,并且last_24_topline中的列为空值。

预期结果: expected results


因此,将相同的架构创建到另一个数据库中,然后仅插入我在上面提供的示例数据,就可以得到预期的结果。我正在进一步测试,将完整的行复制到第二个数据库中,看它是否仍能达到预期的结果。

更新 将所有数据复制到新表中会使问题重新出现。我正在努力降低复制该问题所需的最低限度。

3 个答案:

答案 0 :(得分:0)

使用连接中涉及的列而不是l.account_no,这样,如果左表中没有匹配的行,则将返回top_lines中的行。

SELECT *
FROM top_lines t
LEFT OUTER JOIN last_24_topline AS l ON l.`member_no` = t.`member_no`
       AND l.`mfg` = t.`line_no`
WHERE l.account_no = 32049 OR l.`member_no` IS NULL

或者将帐号过滤器直接放入联接中

SELECT *
FROM top_lines t
LEFT OUTER JOIN last_24_topline AS l ON l.`member_no` = t.`member_no`
       AND l.`mfg` = t.`line_no`
       AND l.account_no = 32049 

答案 1 :(得分:0)

也尝试检测空字符串,也许字段不是NULL,而是空字符串。

chrome://inspect/

如果您需要更多帮助,我将需要“ table last_24_topline”的示例数据以及加入后的预期输出。

第二次尝试,您可以使用此方法:

SELECT *
FROM
    top_lines t
LEFT JOIN
    last_24_topline AS l ON l.member_no = t.member_no AND l.mfg = t.line_no
WHERE
    (l.account_no = '' OR l.account_no = '32049' OR l.account_no IS NULL)

答案 2 :(得分:0)

对于在联接中没有帐号的查询,联接不匹配在last_24_toplines表中的行,但不匹配在where子句中的帐号,因此它会被过滤掉,因此不会被top_lines视为一行,而last_24_topline没有匹配行。

因此,例如top_line表中的这一行

enter image description here

将匹配last_24_toplines中的这一行

enter image description here

,但是两者都将被过滤掉,因为account_no与where子句中的内容不匹配: WHERE l.account_no = 32049 OR l.account_no IS NULL

在联接中具有account_no的查询的查询仍将与top_line中的行匹配,但与last_24_topline中的行匹配,因此您将获得具有top_lines数据的行,其中last_24_topline为空