Trong GROUP BY
và ORDER BY
mệnh đề bạn có thể tham chiếu đến bí danh cột (cột đầu ra) hoặc số thứ tự chẵn của SELECT
Danh sách sản phẩm. Tôi trích dẫn sách hướng dẫn về ORDER BY
:
Mỗi biểu thức có thể là tên hoặc số thứ tự của cột đầu ra (mục danh sách CHỌN) hoặc nó có thể là một biểu thức tùy ý được hình thành từ các giá trị trong đầu ra-cột.
Nhấn mạnh đậm của tôi.
Nhưng trong WHERE
và HAVING
mệnh đề, bạn chỉ có thể tham chiếu đến các cột từ bảng cơ sở (cột đầu vào), vì vậy bạn phải viết chính tả lệnh gọi hàm của mình.
SELECT *, earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon)) AS dist
FROM venues
WHERE earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon)) <= radius
ORDER BY distance;
Nếu bạn muốn biết việc đóng gói phép tính vào CTE hoặc truy vấn con có nhanh hơn hay không, chỉ cần kiểm tra nó với EXPLAIN ANALYZE
. (Tôi nghi ngờ điều đó.)
SELECT *
FROM (
SELECT *
,earth_distance(ll_to_earth(62.0, 25.0), ll_to_earth(lat, lon)) AS dist
FROM venues
) x
WHERE distance <= radius
ORDER BY distance;
Giống như @Mike đã nhận xét, bằng cách khai báo một hàm STABLE
(hoặc IMMUTABLE
) bạn thông báo cho người lập kế hoạch truy vấn rằng kết quả từ một lệnh gọi hàm có thể được sử dụng lại nhiều lần cho các lệnh gọi giống hệt nhau trong một câu lệnh. Tôi trích dẫn sách hướng dẫn ở đây:
Một hàm STABLE không thể sửa đổi cơ sở dữ liệu và được đảm bảo trả về cùng một kết quả đưa ra các đối số giống nhau cho tất cả các hàng trong câu lệnh asingle. Danh mục này cho phép trình tối ưu hóa tối ưu hóa nhiều lệnh gọi của hàm thành một lệnh gọi duy nhất .
Nhấn mạnh đậm của tôi.