MySQL оставил внешнее соединение с предложением where - PullRequest
0 голосов
/ 01 октября 2018

Я пытаюсь использовать следующий запрос 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

Однако это не возвращает строк, так как нет никаких строк account_no в last_24_topline, которые соответствуют.Из всего, что я понимаю и прочитал, этот запрос должен по-прежнему возвращать все строки из top_lines, даже если ни одна строка не совпадает в last_24_topline, так как я проверяю значение или ноль, но это не так.Существуют ли какие-либо параметры или настройки в 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

Однако я не могу использовать эту конструкцию, так как я использую Entity Framework, и вы можете передавать только объединения столбцов, а не значения


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


Итак, создавая ту же схему в другой базе данных и вставляя только приведенные выше примеры данных, я получаю результаты, которые я получаю.ожидать.Далее я тестирую копирование полных строк во вторую базу данных, чтобы увидеть, дает ли она ожидаемые результаты.

update Копирование всех данных в новые таблицы приводит к появлению проблемы.Я пытаюсь сократить до минимума, необходимого для воспроизведения проблемы.

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

Попробуйте также определить пустую строку, возможно, поля не NULL, а пустые строки.

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)

Если вам нужна дополнительная помощь, мне понадобятся примеры данных для "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.id IS NULL
OR
    (l.id IS NOT NULL AND l.account_no = '32049')
0 голосов
/ 02 октября 2018

В запросе без номера счета в соединении объединение соответствует строке в таблице 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.

0 голосов
/ 01 октября 2018

Используйте столбец, участвующий в объединении, вместо 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 
...