php-自我加入并仅在一个表/一侧忽略空值
作者:互联网
我有2张桌子.
一张表定义了客户关系:
CREATE TABLE IF NOT EXISTS `cust_connections` (
`id` int(11) NOT NULL,
`short_name` char(15) COLLATE utf8_unicode_ci NOT NULL,
`source_fnn` char(10) COLLATE utf8_unicode_ci NOT NULL,
`dest_fnn` char(10) COLLATE utf8_unicode_ci NOT NULL,
`service_type` char(32) COLLATE utf8_unicode_ci NOT NULL,
`ladder_side` char(10) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `cust_connections` (`id`, `short_name`, `source_fnn`, `dest_fnn`, `service_type`, `ladder_side`) VALUES
(1, 'cust1', 'N2843453A', '', 'HD_300_Connect', 'src only'),
(2, 'cust2', '', 'N2843600A', 'HD_300_Connect', 'dest only'),
(3, 'cust3', 'N2720257O', 'N2731164O', 'DVB25_188byte', 'both'),
(4, 'cust4', 'N27xxx7O', 'N2731164O', 'DVB25_188byte', 'src ukn'),
(5, 'cust4', 'N27xxx7O', '', 'DVB25_188byte', 'ukn +blk');
ALTER TABLE `cust_connections`
ADD PRIMARY KEY (`id`);
ALTER TABLE `cust_connections`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=18;
另一个表定义了设备:
CREATE TABLE IF NOT EXISTS `cust_port` (
`id` smallint(11) NOT NULL,
`system_name` char(32) COLLATE utf8_unicode_ci NOT NULL,
`slot_no` char(2) COLLATE utf8_unicode_ci NOT NULL,
`port_no` char(2) COLLATE utf8_unicode_ci NOT NULL,
`port_fnn` char(9) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `cust_port` (`id`, `system_name`, `slot_no`, `port_no`, `port_fnn`) VALUES
(1, '01-06C2:source', '7', '1', 'N2843453A'),
(2, '01-27B4:dest', '1', '2', 'N2843600A'),
(3, '01-27B6:source+dst', '17', '3', 'N2720257O'),
(4, '01-27B6:dst+src', '17', '3', 'N2731164O'),
(5, '01-32C6:dup_fnn1', '1', '2', 'N2845070O'),
(26, '01-32C6:dup_fnn2', '1', '3', 'N2845070O'),
(27, '01-32D6:no_fnn', '1', '4', ''),
(28, '01-32D6:diff_fnn', '1', '4', 'x123456');
ALTER TABLE `cust_port`
ADD PRIMARY KEY (`id`);
ALTER TABLE `cust_port`
MODIFY `id` smallint(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=29;
SQl结果是:
cc_id short_name source_fnn dest_fnn service_type ladder_side src_system_name src_slot_no src_port_no src_port_fnn dst_system_name dst_slot_no dst_port_no dst_port_fnn
1 cust1 N2843453A HD_300_Connect src only 01-06C2:source 7 1 N2843453A 01-32D6:no_fnn 1 4
2 cust2 N2843600A HD_300_Connect dest only 01-32D6:no_fnn 1 4 01-27B4:dest 1 2 N2843600A
3 cust3 N2720257O N2731164O DVB25_188byte both 01-27B6:source+dst 17 3 N2720257O 01-27B6:dst+src 17 3 N2731164O
4 cust4 N27xxx7O N2731164O DVB25_188byte src ukn NULL NULL NULL NULL 01-27B6:dst+src 17 3 N2731164O
5 cust4 N27xxx7O DVB25_188byte ukn +blk NULL NULL NULL NULL 01-32D6:no_fnn 1 4
我正在对两个表进行联接.
问题是,如果port_fnn为空,我想排除该行,但是如果任何客户源或目标fnns为空,则显示该行.
我正在做一个左(自)联接,以在源和目标fnn上与设备fnn进行匹配.不幸的是,我的客户fnns必须能够具有空值.
如果设备表中没有空值,则我的查询效果很好.
我的查询是:
SELECT
cc.id AS cc_id, short_name,source_fnn, dest_fnn, service_type,ladder_side,
src.system_name AS src_system_name,
src.slot_no AS src_slot_no,
src.port_no AS src_port_no,
src.port_fnn AS src_port_fnn,
dst.system_name AS dst_system_name,
dst.slot_no AS dst_slot_no,
dst.port_no AS dst_port_no,
dst.port_fnn AS dst_port_fnn
FROM cust_connections cc
LEFT JOIN cust_port src on cc.source_fnn=src.port_fnn
LEFT JOIN cust_port dst on cc.dest_fnn=dst.port_fnn
在我的结果集中:
第1行-仅具有源fnn.我希望目标字段的结果为空,即:
cc_id short_name source_fnn dest_fnn service_type ladder_side src_system_name src_slot_no src_port_no src_port_fnn dst_system_name dst_slot_no dst_port_no dst_port_fnn
1 cust1 N2843453A HD_300_Connect src only 01-06C2:source 7 1 N2843453A NULL NULL NULL NULL
该查询正在检测空的fnn,并填充没有关联的fnn的设备.即:01-32D6:no_fnn.
第2行的source_system_name和第5行的dst_system_name会发生相同的问题.
解决方法:
”(空字符串)不为NULL. (哪个sqlfiddle输出为“(null)”.)
在文字中,请勿输入“ NULL”或“< NULL>”或“ null”或“(null)”来引用空字符串,就像您最初在问题中所做的那样.要清楚什么是“”,什么是NULL.
”=”但为NULL<>空值.因此,当相等测试涉及到“”时,您的LEFT JOIN会在cc.source_fnn和src.port_fnn列之间以及在cc.dest_fnn和cust_port port_fnn列之间找到匹配项.但是您不希望LEFT JOIN匹配那些行.
您可以这样说:
>将所有_fnn列声明为可空,即,使用NULL(默认值)而不是NOT NULL,并在您现在使用”(空字符串)的表中使用NULL.然后您的查询将给出正确的答案!
>需要port_fnn<> ”:
FROM cust_connections cc
LEFT JOIN cust_port src
ON cc.source_fnn=src.port_fnn AND cc.source_fnn <> ''
LEFT JOIN cust_port dst
ON cc.dest_fnn=dst.port_fnn AND cc.dest_fnn <> '';
>在您与之保持连接之前,从cust_port中删除这些行:
FROM cust_connections cc
LEFT JOIN
(SELECT * FROM cust_port WHERE port_fnn <> ''
) src
ON cc.source_fnn=src.port_fnn
LEFT JOIN
(SELECT * FROM cust_port WHERE port_fnn <> ''
) dst
ON cc.dest_fnn=dst.port_fnn;
Sqlfiddle for 1 using NULL和for 2 & 3 using ”.它们添加了第二个cust_port行,其中缺少port_fnn,以表明上述内容提供了正确的结果.与”一起使用的查询会错误地从中生成其他虚假行.
如果要使LEFT JOIN中的NULL显示为输出中的空字符串,则可以对这些列使用IFNULL:
IFNULL(dst.port_fnn,”)AS dst_port_fnn
标签:null,left-join,string,mysql,php 来源: https://codeday.me/bug/20191120/2046927.html