2016-10-19 11 views
1

を設定できます:条件を複製することは、異なる結果が、私は次のクエリを持って

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 
    )) 
) 

あなたが見ることができるように、二つの条件が同一であるので、私は条件のいずれかを削除した場合、クエリは同じを与えるべきです結果。ただし、条件の両方がある場合は、クエリのうちの1つのみを使用する場合と比べて、クエリが異なる結果を返します。

私のケースでは、条件(下記)で使用される内部クエリが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の行のみが含まれます。いずれかの条件のみが使用される場合、OrganisationId115,131または153に等しい行も含まれます。

ので、下記のクエリが正しい結果を生成:

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 
    )) 
) 

をただし、重複した条件を持つこの質問の最初のクエリでは、正しい結果が得られません。

誰でもこの動作について説明できますか?

編集

私はそれはMariaDBに問題があるかもしれないと思います。ここでは、正しい結果を与えるMySQLとSQL Fiddleです。 SQL FiddleでMariaDBを使用することはできないようです。 MariaDBでクエリをテストする他の簡単な方法はありますか?

答えて

0

これは、新しいバージョンのMySQLとMariaDBの問題であるようです。

私はこれらのデータベースに問題が発生します。

  • のMySQL 5.7.17
  • MariaDB 10.1.25

しかし、それは、これらのデータベースに正常に動作します:

  • のMySQL 5.6.35
  • MySQL 5.5.51

データベースでこの問題をテストするには、次のクエリを実行します。最後のクエリは4行を返す必要があります。行が1つしか返されない場合、データベースのバージョンはこの問題の影響を受けます。

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

関連する問題