我有以下查询:
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
))
)
如您所见,这两个条件是相同的,因此如果我删除了其中一个条件,则查询应该给出相同的结果。但是,当两个条件都存在时,查询返回的结果与仅使用其中一个条件时返回的结果不同!
条件(下面)中使用的内部查询在我的情况下返回115,131,153
。
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
使用这两个条件时,结果只包含OrganisationId = 1
的行。如果仅使用其中一个条件,则还会包含OrganisationId
等于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
))
)
此问题中的第一个查询具有重复条件,但不会给出正确的结果。
有人可以解释这种行为吗?
修改
我认为这可能是MariaDB的一个问题。这是带有MySQL的SQL Fiddle,给出了正确的结果。似乎不可能在SQL Fiddle中使用MariaDB。有没有其他简单的方法来测试MariaDB中的查询?
答案 0 :(得分:0)
这似乎是较新版本的MySQL和MariaDB的问题。
我在这些数据库中遇到了这个问题:
但它在这些数据库中运行良好:
要针对此问题测试数据库,请执行以下查询。最终查询应该返回4行。如果它只返回一行,那么您的数据库版本会受到该问题的影响。
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验证:https://bugs.mysql.com/bug.php?id=87339
编辑2018-10-30 这是测试它的小提琴。这个问题也存在于MySQL 8.0中。