SELECT From MySQL View With HAVING Clause Returns Empty Result Set

安稳与你 提交于 2019-12-09 03:38:03

问题


My business partner and I are having issues selecting from a MySQL view that has a HAVING clause.

The query simply selects a few fields from the view, determines a distance dynamically with a few calculations, and aliases it as 'distance' - then limits the results to those rows with a distance less than a supplied variable.

The distance is calculated using the Haversine formula, referenced by Google Maps: https://developers.google.com/maps/articles/phpsqlsearch

Here is what I know:

1) When the HAVING clause is removed from the query, it returns all the results in the view successfully, including the calculated 'distance' for each row

2) When the HAVING clause is added to the query, it returns an empty result set

3) We also tried swapping the variable in the HAVING clause to a static number - this also returned an empty result set

The contents of the view seem irrelevant since everything works without the HAVING clause.

Here is the query:

SELECT 
restaurantName, 
restaurantID, 
locationID, 
locationCity, 
locationState, 
locationAddress, 
locationLatitude, 
locationLongitude,
( 3959 * acos( cos( radians('%s') ) * cos( radians( locationLatitude ) ) * cos( radians( locationLongitude ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( locationLatitude ) ) ) ) AS distance 
FROM newView 
HAVING distance < '%s' 
ORDER BY distance

Remember that the view calculates the 'distance' for every selected row perfectly without the HAVING clause, so we are convinced the problem lies there... when we take it out, everything works but every row in the view is returned.

Any ideas why the HAVING clause is returning an empty set? Is the HAVING clause not compatible with views?


回答1:


Try this:

select * from (
    SELECT 
    restaurantName, 
    restaurantID, 
    locationID, 
    locationCity, 
    locationState, 
    locationAddress, 
    locationLatitude, 
    locationLongitude,
    ( 3959 * acos( cos( radians('%s') ) * cos( radians( locationLatitude ) ) * cos( radians( locationLongitude ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( locationLatitude ) ) ) ) AS distance 
    FROM newView
) S
where distance < '%s' 
ORDER BY distance



回答2:


The HAVING clause is meant to be used on aggregated data when you are grouping rows together using the GROUP BY clause. Since you are operating on each row individually, you should replace HAVING with a WHERE clause. See this example for details.

Using HAVING on non-aggregate columns in your SELECT list is non-standard behaviour which MySQL supports, but behaviour that shouldn't be relied on. Even the MySQL reference discourages it:

Do not use HAVING for items that should be in the WHERE clause. For example, do not write the following:

SELECT col_name FROM tbl_name HAVING col_name > 0;

Write this instead:

SELECT col_name FROM tbl_name WHERE col_name > 0;

As an aside: if you are passing arguments from the user to your query (with the %s), make sure you look into prepared statements. Otherwise you may have a glaring security flaw on your hands.



来源:https://stackoverflow.com/questions/9730873/select-from-mysql-view-with-having-clause-returns-empty-result-set

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!