Ваша проблема заключается в том, что distance
здесь есть псевдоним в SELECT
, который пока недоступен в предложении WHERE
. В отдельной таблице это еще один столбец.
Таким образом, вместо того, чтобы distance
в WHERE
, повторите всю операцию:
sin(radians(myLat)) * sin(radians(latitude))))
Так что ваша статья WHERE
бы стать:
WHERE Restaurants.RestaurantID = BusinessHours.RestaurantID AND
(sin(radians(myLat)) * sin(radians(latitude))))) < searchDist AND
(sin(radians(myLat)) * sin(radians(latitude))))) < Restaurants.deliveryDistance
Я добавил вмещающих скобки для дальнейшего очерчивания и добавить дополнительная ясность.
Редактировать в ответ на комментарий от OP:
Это повторение calcuations просто так, как это должно быть сделано в SQL если вы хотите повторно использовать значение из SELECT
в WHERE
того же запроса. Как правило, повторный расчет не является большой проблемой (я считаю, что он имеет некоторое кэширование, чтобы помочь с этим), и я подозреваю, что эти вычисления, которые являются прямыми вычислениями в математике, не являются исключением, поэтому я бы рекомендовал пойти с этим повторяющийся метод.
Если вы наткнулись в случае, когда что-то было по-настоящему дорогой запрос, и вы обнаружили, что встроенные в кэшированиях делали повторяя выражение дорогой, есть два варианта:
Один использовать CTE , который включает выражение WITH
. Это полезно для независимых запросов, т. Е. Запросов, которые не зависят от ввода запроса, в котором вы его будете использовать. Это в основном функционирует как временная таблица запросов. Однако в вашем случае ваше повторное выражение не является постоянным - оно изменяется в зависимости от конкретной строки из ваших JOIN
ed tables - и поэтому CTE не сработает для вас.
Другой обернуть SELECT
внутри другого SELECT
, передвигая положение WHERE
к внешнему SELECT
, так что distance
столбец доступен вам во внешнем SELECT
.Однако при таком подходе вам нужно будет убедиться, что ваш внутренний SELECT
вернул все необходимые столбцы, которые внешний SELECT
необходимо в своем предложении WHERE
, что потребует добавления столбцов в ваш случай, и в целом просто кажется более сложным вопрос, чем он должно быть, хотя сложность, вероятно, была бы уменьшена, если бы использовался новый синтаксис JOIN
, где критерии были перемещены за пределами WHERE
и JOIN ... ON
.
Так что, опять же, я бы рекомендовал повторить выражение. Только попытайтесь оптимизировать, если это абсолютно необходимо.
Редактировать в repsonse на 2-й комментарий от OP:
Он не должен иметь ничего общего с ли или не соединены таблицы - ссылающийся не сглаженный столбец из SELECT
не будет работать в HAVING
или WHERE
в особой таблице.
например.
mydb=# create table bar (id serial, val decimal);
CREATE TABLE
mydb=# insert into bar (val) values (1.2), (1.1), (3.2);
INSERT 0 3
mydb=# select * from bar;
id | val
----+-----
1 | 1.2
2 | 1.1
3 | 3.2
(3 rows)
mydb=# select id, val, sin(val) from bar;
id | val | sin
----+-----+---------------------
1 | 1.2 | 0.932039085967226
2 | 1.1 | 0.891207360061435
3 | 3.2 | -0.0583741434275801
(3 rows)
mydb=# select id, val, sin(val) as narf from bar;
id | val | narf
----+-----+---------------------
1 | 1.2 | 0.932039085967226
2 | 1.1 | 0.891207360061435
3 | 3.2 | -0.0583741434275801
(3 rows)
mydb=# select id, val, sin(val) as narf from bar having narf > 0;
ERROR: column "narf" does not exist
LINE 1: select id, val, sin(val) as narf from bar having narf > 0;
^
mydb=# select id, val, sin(val) as narf from bar having sin(val) > 0;
ERROR: column "bar.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: select id, val, sin(val) as narf from bar having sin(val) > ...
^
mydb=# select id, val, sin(val) as narf from bar where narf > 0;
ERROR: column "narf" does not exist
LINE 1: select id, val, sin(val) as narf from bar where narf > 0;
^
mydb=# select id, val, sin(val) as narf from bar where sin(val) > 0;
id | val | narf
----+-----+-------------------
1 | 1.2 | 0.932039085967226
2 | 1.1 | 0.891207360061435
(2 rows)
Привет, Я думал об этом, но, похоже, неэффективно делать расчет дважды. Что еще более важно, мне нужен столбец расстояния в таблице результатов, который я возвращаю как json. – Teboto
Нет ничего плохого в том, чтобы наложить его на 'расстояние' в' SELECT' - вы просто не можете использовать его в 'WHERE' - но я бы не стал беспокоиться о производительности с повторными вычислениями в целом, особенно для тех, которые носят более простой характер. Подробнее о редактировании моего ответа. – khampson
Спасибо, я рассмотрю ваши решения. Я просто очень смущен, почему псевдоним 'distance' доступен для использования в' WHERE' или 'HAVING' в выражении' SELECT', в котором я не присоединяюсь к таблицам. Может ли быть, что объединенные «SELECT» и индивидуальные «SELECT» выполняются в разных порядках? Я редактировал свой вопрос, чтобы включить код из отдельного 'SELECT' для уточнения. – Teboto