조건을 복제하면 다른 결과 집합이 나타납니다.
다음과 같은 문의 사항이 있습니다.
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에서 쿼리를 테스트할 수 있는 다른 쉬운 방법이 있습니까?
MySQL 및 MariaDB의 최신 버전에서 문제가 발생한 것으로 보입니다.
다음 데이터베이스에서 문제가 발생합니다.
- MySQL 5.7.17
- MariaDB 10.1.25
그러나 이러한 데이터베이스에서는 잘 작동합니다.
- MySQL 5.6.35
- MySQL 5.5.51
데이터베이스에 문제가 있는지 테스트하려면 다음 쿼리를 수행합니다.마지막 쿼리는 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에서도 이 문제가 발생합니다.
https://www.db-fiddle.com/f/5SAJZJosQXMZsDmU1Lmi8X/0
언급URL : https://stackoverflow.com/questions/40129204/duplicating-the-condition-gives-a-different-result-set
'programing' 카테고리의 다른 글
| 목록에서 "반복/교체가 있는 순열"을 가져오려면 어떻게 해야 합니까?(목록 자체가 있는 데카르트 제품) (0) | 2023.11.05 |
|---|---|
| 봄 :: 히카리 1조 출발...응용 프로그램을 실행할 때 이 줄에 걸려 버립니다. (0) | 2023.11.05 |
| printf()를 사용하는 데 #include가 필요하지 않은 이유는 무엇입니까? (0) | 2023.11.05 |
| 어떻게 요일과 일년의 달을 얻을 수 있습니까? (0) | 2023.11.05 |
| 기본 dict를 dict로 변환하는 방법? (0) | 2023.11.05 |