這有點奇怪:我有以下的MySQL存儲過程(或函數),大多數可以安全地忽略,除非需要了解完整的圖片。問題是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子句好像對待十進制值distanceFromUsersPostcode爲VARCHAR(或字符串)值。
它訂單的結果形式:
0.4,101.9,102.8,11.1,11.9
同樣可以如果我用標記爲* 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')用零填充到左邊的pad。然而,不幸的是,它沒有像預期的那樣工作,就像以前一樣。 –
但是,這讓我想到了MySQL正在應用詞法排序(所以這兩種類型匹配)的事實。我設法通過使用WHEN'LOCATION'THEN(distanceFromUsersPostcode + 10000)來使查詢工作。這已經解決了這個問題,但讓我更加關注。 MySQL現在正在執行詞法排序,而不是按數字(或日期)進行排序,具體取決於提供的排序。我在別處讀過這可能會導致查詢運行速度慢得多。如果是這種情況,我會更快樂地複製原來顯示的代碼段。不太優雅但更快速的查詢。有什麼想法嗎? –
我很高興你能工作。這種排序要求並不常見。你能不能以不同的方式思考你的要求? –