Mysql 复制条件会产生不同的结果集
我有以下疑问:Mysql 复制条件会产生不同的结果集,mysql,mariadb,Mysql,Mariadb,我有以下疑问: SELECT * FROM dp_organisation_member t82 WHERE ( t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, ( SELECT GROUP_CONCAT(`Ids`) FROM ( SELECT @Level := @Level + '1' `Level`, @Ids := ( SELECT G
SELECT *
FROM dp_organisation_member t82
WHERE (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, (
SELECT GROUP_CONCAT(`Ids`)
FROM (
SELECT @Level := @Level + '1' `Level`, @Ids := (
SELECT GROUP_CONCAT(`OrganisationId`)
FROM dp_organisation
WHERE FIND_IN_SET(`ParentId`, @Ids)
) `Ids`
FROM (SELECT @Ids := '1', @Level := '0') temp1
INNER JOIN dp_organisation ON NOT(ISNULL(@Ids))
) temp2
))
) AND (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, (
SELECT GROUP_CONCAT(`Ids`)
FROM (
SELECT @Level := @Level+'1' `Level`, @Ids := (
SELECT GROUP_CONCAT(`OrganisationId`)
FROM dp_organisation
WHERE FIND_IN_SET(`ParentId`, @Ids)
) `Ids`
FROM (SELECT @Ids := '1', @Level := '0') temp1
INNER JOIN dp_organisation ON NOT(ISNULL(@Ids))
) temp2
))
)
正如您所看到的,这两个条件是相同的,因此如果我删除其中一个条件,查询将给出相同的结果。但是,当两个条件都存在时,查询返回的结果与仅使用其中一个条件时不同
在我的例子中,条件(下面)中使用的内部查询返回115131153
SELECT GROUP_CONCAT(`Ids`)
FROM (
SELECT @Level := @Level+'1' `Level`, @Ids := (
SELECT GROUP_CONCAT(`OrganisationId`)
FROM dp_organisation
WHERE FIND_IN_SET(`ParentId`, @Ids)
) `Ids`
FROM (SELECT @Ids := '1', @Level := '0') temp1
INNER JOIN dp_organisation ON NOT(ISNULL(@Ids))
) temp2
使用这两个条件时,结果仅包括OrganizationId=1
的行。当仅使用其中一个条件时,还包括organizationId
等于115
、131
或153
的行
因此,下面的查询将生成正确的结果:
SELECT *
FROM dp_organisation_member t82
WHERE (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, (
SELECT GROUP_CONCAT(`Ids`)
FROM (
SELECT @Level := @Level + '1' `Level`, @Ids := (
SELECT GROUP_CONCAT(`OrganisationId`)
FROM dp_organisation
WHERE FIND_IN_SET(`ParentId`, @Ids)
) `Ids`
FROM (SELECT @Ids := '1', @Level := '0') temp1
INNER JOIN dp_organisation ON NOT(ISNULL(@Ids))
) temp2
))
)
SELECT *
FROM dp_organisation_member t82
WHERE (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, "115,131,153")
) AND (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, (
SELECT GROUP_CONCAT(`Ids`)
FROM (
SELECT @Level := @Level+'1' `Level`, @Ids := (
SELECT GROUP_CONCAT(`OrganisationId`)
FROM dp_organisation
WHERE FIND_IN_SET(`ParentId`, @Ids)
) `Ids`
FROM (SELECT @Ids := '1', @Level := '0') temp1
INNER JOIN dp_organisation ON NOT(ISNULL(@Ids))
) temp2
))
)
此外,如果我将其中一个内部查询替换为该查询的结果,则该查询将给出正确的结果:
SELECT *
FROM dp_organisation_member t82
WHERE (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, (
SELECT GROUP_CONCAT(`Ids`)
FROM (
SELECT @Level := @Level + '1' `Level`, @Ids := (
SELECT GROUP_CONCAT(`OrganisationId`)
FROM dp_organisation
WHERE FIND_IN_SET(`ParentId`, @Ids)
) `Ids`
FROM (SELECT @Ids := '1', @Level := '0') temp1
INNER JOIN dp_organisation ON NOT(ISNULL(@Ids))
) temp2
))
)
SELECT *
FROM dp_organisation_member t82
WHERE (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, "115,131,153")
) AND (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, (
SELECT GROUP_CONCAT(`Ids`)
FROM (
SELECT @Level := @Level+'1' `Level`, @Ids := (
SELECT GROUP_CONCAT(`OrganisationId`)
FROM dp_organisation
WHERE FIND_IN_SET(`ParentId`, @Ids)
) `Ids`
FROM (SELECT @Ids := '1', @Level := '0') temp1
INNER JOIN dp_organisation ON NOT(ISNULL(@Ids))
) temp2
))
)
然而,这个问题中的第一个查询具有重复的条件,不能给出正确的结果
有人能解释一下这种行为吗
编辑
我想这可能是MariaDB的问题。下面是MySQL的一个示例,给出了正确的结果。在sqlfiddle中使用MariaDB似乎是不可能的。在MariaDB中还有其他简单的方法来测试查询吗?对于MySQL和MariaDB的新版本来说,这似乎是一个问题 我在这些数据库中遇到了这个问题:
- MySQL 5.7.17
- MariaDB 10.1.25
- MySQL 5.6.35
- MySQL 5.5.51
CREATE TABLE `dp_organisation` (
`OrganisationId` bigint(32) NOT NULL AUTO_INCREMENT,
`ParentId` bigint(32) DEFAULT NULL,
PRIMARY KEY (`OrganisationId`)
) ENGINE=MyISAM AUTO_INCREMENT=154 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `dp_organisation_member` (
`OrganisationId` bigint(32) NOT NULL,
`UserId` bigint(32) NOT NULL,
PRIMARY KEY (`OrganisationId`,`UserId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `dp_organisation` VALUES (1,NULL),(2,NULL),(3,2),(115,1),(131,1),(153,115);
INSERT INTO `dp_organisation_member` VALUES (1,1),(2,2),(3,3),(115,4),(131,5),(153,6);
SELECT *
FROM dp_organisation_member t82
WHERE (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, (
SELECT GROUP_CONCAT(`Ids`)
FROM (
SELECT @Level := @Level + '1' `Level`, @Ids := (
SELECT GROUP_CONCAT(`OrganisationId`)
FROM dp_organisation
WHERE FIND_IN_SET(`ParentId`, @Ids)
) `Ids`
FROM (SELECT @Ids := '1', @Level := '0') temp1
INNER JOIN dp_organisation ON NOT(ISNULL(@Ids))
) temp2
))
) AND (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, (
SELECT GROUP_CONCAT(`Ids`)
FROM (
SELECT @Level := @Level+'1' `Level`, @Ids := (
SELECT GROUP_CONCAT(`OrganisationId`)
FROM dp_organisation
WHERE FIND_IN_SET(`ParentId`, @Ids)
) `Ids`
FROM (SELECT @Ids := '1', @Level := '0') temp1
INNER JOIN dp_organisation ON NOT(ISNULL(@Ids))
) temp2
))
)
编辑
MySQL已验证该漏洞:
编辑2018-10-30
这是一把用来测试它的小提琴。MySQL 8.0中也存在这个问题
这似乎是MySQL和MariaDB新版本的一个问题 我在这些数据库中遇到了这个问题:
- MySQL 5.7.17
- MariaDB 10.1.25
- MySQL 5.6.35
- MySQL 5.5.51
CREATE TABLE `dp_organisation` (
`OrganisationId` bigint(32) NOT NULL AUTO_INCREMENT,
`ParentId` bigint(32) DEFAULT NULL,
PRIMARY KEY (`OrganisationId`)
) ENGINE=MyISAM AUTO_INCREMENT=154 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `dp_organisation_member` (
`OrganisationId` bigint(32) NOT NULL,
`UserId` bigint(32) NOT NULL,
PRIMARY KEY (`OrganisationId`,`UserId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `dp_organisation` VALUES (1,NULL),(2,NULL),(3,2),(115,1),(131,1),(153,115);
INSERT INTO `dp_organisation_member` VALUES (1,1),(2,2),(3,3),(115,4),(131,5),(153,6);
SELECT *
FROM dp_organisation_member t82
WHERE (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, (
SELECT GROUP_CONCAT(`Ids`)
FROM (
SELECT @Level := @Level + '1' `Level`, @Ids := (
SELECT GROUP_CONCAT(`OrganisationId`)
FROM dp_organisation
WHERE FIND_IN_SET(`ParentId`, @Ids)
) `Ids`
FROM (SELECT @Ids := '1', @Level := '0') temp1
INNER JOIN dp_organisation ON NOT(ISNULL(@Ids))
) temp2
))
) AND (
t82.`OrganisationId` = '1' OR FIND_IN_SET(t82.`OrganisationId`, (
SELECT GROUP_CONCAT(`Ids`)
FROM (
SELECT @Level := @Level+'1' `Level`, @Ids := (
SELECT GROUP_CONCAT(`OrganisationId`)
FROM dp_organisation
WHERE FIND_IN_SET(`ParentId`, @Ids)
) `Ids`
FROM (SELECT @Ids := '1', @Level := '0') temp1
INNER JOIN dp_organisation ON NOT(ISNULL(@Ids))
) temp2
))
)
编辑
MySQL已验证该漏洞:
编辑2018-10-30
这是一把用来测试它的小提琴。MySQL 8.0中也存在这个问题