1

DataMapper (CodeIgniter の ORM) によって生成されたクエリがあり、あるサーバーでは結果を返しますが、別のサーバーでは返しません。

両方のデータベースはまったく同じです。このクエリは、MYSQL バージョン 5.1.41、5.1.63、および 5.5.20 のサーバーで機能し、5.1.52 では失敗します。

クエリは次のとおりです。

SELECT DISTINCT `clients`.`id`
FROM (`clients`)

LEFT OUTER JOIN `clients_locations`
    clients_locations ON `clients`.`id` = `clients_locations`.`client_id`

LEFT OUTER JOIN `locations`
    locations ON `locations`.`id` = `clients_locations`.`location_id`

LEFT OUTER JOIN `reports`
    location_reports ON `locations`.`id` = `location_reports`.`location_id`

WHERE
    `location_reports`.`id` =  1
AND 
    `clients`.`id` =  2

いくつかのテストを行ったところ、次のことがわかりました。

WHERE 句が 1 つしかない場合は、結果が返されます。演算子のいずれかを LIKE、!= などに
変更 すると、結果が返されます。AND を OR に変更すると、結果が返されます。

同様のクエリがサイト全体で使用されているため、なぜこれが失敗しているのかわかりません。例えば:

SELECT DISTINCT `clients`.`id`
FROM (`clients`)

LEFT OUTER JOIN `clients_locations`
    clients_locations ON `clients`.`id` = `clients_locations`.`client_id`

LEFT OUTER JOIN `locations`
    locations ON `locations`.`id` = `clients_locations`.`location_id`

LEFT OUTER JOIN
    `locations_questionnaires` location_locations_questionnaires 
ON 
    `locations`.`id` = `location_locations_questionnaires`.`location_id`

WHERE
    `location_locations_questionnaires`.`questionnaire_id` =  3
AND 
     `clients`.`id` =  2

上記のすべてのサーバーで正しい結果を返します。

誰もこれを見たことがありますか?

明確にするために:

SQL は ORM によって生成されるため、編集できません。

両方のデータセットはまったく同じです。

問題は、一方のサーバーではクエリが結果を返さないのに、もう一方のサーバーでは結果を返さない理由です。

UPDATE : サーバーを 5.1.61 にアップグレードしたところ、クエリは正常に実行されます。5.1.52 のバグのようです。

4

2 に答える 2

2

外部結合テーブルのWHERE条件、例:

WHERE location_reports.id =  1

効果的に外側の結合を内側の結合に変えます。その条件をJOIN条件に移動すると、正しく機能します(すでにお気づきのとおり)。

その理由は、外部結合行には条件の値がないため、JOINのlocation_reports.idにWHERE条件が適用され、条件がfalseになり、結果から削除されるためです。

于 2012-06-14T11:59:06.487 に答える
1

このようにしてみてください:

SELECT DISTINCT `clients`.`id`
FROM (`clients`)

LEFT OUTER JOIN `clients_locations`
    clients_locations ON `clients`.`id` = `clients_locations`.`client_id`
    AND `clients`.`id` =  2

LEFT OUTER JOIN `locations`
    locations ON `locations`.`id` = `clients_locations`.`location_id`

LEFT OUTER JOIN `reports`
    location_reports ON `locations`.`id` = `location_reports`.`location_id`
    AND `location_reports`.`id` =  1
于 2012-06-14T12:09:41.570 に答える