これはちょっと変わったことです:以下のMySQL Stored Proc(または関数)があります。完全な画像を理解する必要がない限り、大多数は無視できます。問題は、ORDER BY句です。ORDER BY句のMySQL IFステートメント
BEGIN
SELECT DISTINCT e.*, (3959 * acos(cos(radians(in_latitude)) * cos(radians(e.address_latitude))
* cos(radians(e.address_longitude) - radians(in_longitude)) + sin(radians(in_latitude))
* sin(radians(e.address_latitude)))) AS distanceFromUsersPostcode
FROM event e
INNER JOIN event_organiser eo on e.event_organiser_id = eo.id
WHERE (e.event_name LIKE in_search OR e.address_town LIKE in_search OR e.address_county LIKE in_search OR eo.event_organiser_name LIKE in_search)
AND e.start_date_time >= in_start_date
AND e.start_date_time <= in_end_date
AND e.enabled = true
HAVING distanceFromUsersPostcode < in_maxDistanceFromUser
/*
* 1 *
ORDER BY distanceFromUsersPostcode
* 2 *
ORDER BY IF(in_orderBy='LOCATION', CAST(distanceFromUsersPostcode AS DECIMAL), e.start_date_time) ASC;
*/
ORDER BY
CASE in_orderBy
WHEN 'LOCATION' THEN distanceFromUsersPostcode
ELSE e.start_date_time
END
ASC;
END
さて問題はこれで、ORDER BY句現在のコメントを外しORDERはVARCHAR(または列)の値としてDECIMAL値distanceFromUsersPostcodeを治療するためのようです。
それは形式で結果順序付け:
0.4、101.9、102.8、11.1、11.9
Iしかし* 2 *
として標識された変異体を使用した場合ならば同じことが、言うことができるが私は* 1 *として示さ元バリアントに戻す、結果は予想通り注文することになります。
0.4、11.1、11.9、101.9、102.8
私の推測をIF関数(* 2 *)内で使用されている場合、MySQLはdistanceFromUsersPostcode変数をVARCHARとして扱いました。したがって、これをDECIMALにキャストしようとしました。しかし、これは効果がありません。
ここで何が起こっているのか誰にも分かりますか?
予想通り、以下の行為が、それはクエリ全体を複製として当然の非常にエレガントではありません。
BEGIN
IF in_orderBy='LOCATION' THEN
SELECT DISTINCT e.*, (3959 * acos(cos(radians(in_latitude)) * cos(radians(e.address_latitude))
* cos(radians(e.address_longitude) - radians(in_longitude)) + sin(radians(in_latitude))
* sin(radians(e.address_latitude)))) AS distanceFromUsersPostcode
FROM event e
INNER JOIN event_organiser eo on e.event_organiser_id = eo.id
WHERE (e.event_name LIKE in_search OR e.address_town LIKE in_search OR e.address_county LIKE in_search OR eo.event_organiser_name LIKE in_search)
AND e.start_date_time >= in_start_date
AND e.start_date_time <= in_end_date
AND e.enabled = true
HAVING distanceFromUsersPostcode < in_maxDistanceFromUser
ORDER BY distanceFromUsersPostcode;
ELSE
SELECT DISTINCT e.*, (3959 * acos(cos(radians(in_latitude)) * cos(radians(e.address_latitude))
* cos(radians(e.address_longitude) - radians(in_longitude)) + sin(radians(in_latitude))
* sin(radians(e.address_latitude)))) AS distanceFromUsersPostcode
FROM event e
INNER JOIN event_organiser eo on e.event_organiser_id = eo.id
WHERE (e.event_name LIKE in_search OR e.address_town LIKE in_search OR e.address_county LIKE in_search OR eo.event_organiser_name LIKE in_search)
AND e.start_date_time >= in_start_date
AND e.start_date_time <= in_end_date
AND e.enabled = true
HAVING distanceFromUsersPostcode < in_maxDistanceFromUser
ORDER BY e.start_date_time;
END IF;
END
ご意見ありがとうございます。あなたが示唆したようにコンパイルされず、LPAD(CAST(distanceFromUsersPostcode as CHAR)、6、 '0')を左パッドに0に変更しました。しかし、残念ながら、それは以前と同じ問題ではありませんでした。 –
しかし、これはMySQLがレキシカルソートを適用しているという事実を考えています(2つのタイプが一致します)。私は、WHEN 'LOCATION' THEN(distanceFromUsersPostcode + 10000)を使用してクエリを動作させることができました。これで問題は解決しましたが、大きな懸念につながります。 MySQLは現在、どのソートが提供されているかに応じて、数値(または日付)でソートするのではなく、レキシカルソートを実行しています。私は他の場所でこれを読むと、クエリの実行がずっと遅くなる可能性があります。これが当てはまる場合、最初に表示されたコードセグメントを複製するのは幸いです。あまりエレガントではありませんが、より高速なクエリ何かご意見は? –
あなたはそれが働いてうれしいです。このソート要件は珍しいことです。別の方法であなたの要求を考えるのではないでしょうか? –