Подтвердить что ты не робот

SQL Server AS с псевдонимом столбца в инструкции WHERE

Я хочу выполнить запрос, в котором я переименовываю один из столбцов, используя оператор "AS", и повторно использую это имя псевдонимого столбца в инструкции "WHERE". Ниже приведен пример:

SELECT lat AS latitude 
FROM poi_table 
WHERE latitude < 500

Проблема здесь в том, что SQL Server не нравится этот запрос из-за предложения WHERE и имени оператора AS, на которое ссылаются в предложении WHERE. Может ли кто-нибудь объяснить, почему это происходит, и что я могу сделать, чтобы исправить мою ситуацию?

Предположим, что у меня должна быть формула, которую я использовал в SELECT-части запроса, как мне это решить?

SELECT *, 
( 6371*1000 * acos( cos( radians(42.3936868308) ) * cos( radians( lat ) ) * cos( radians( lon ) - radians(-72.5277256966) ) + sin( radians(42.3936868308) ) * sin( radians( lat ) ) ) ) 
AS distance
FROM poi_table 
WHERE distance < 500;
4b9b3361

Ответ 1

SQL обычно не позволяет ссылаться на псевдонимы столбцов в предложениях WHERE, GROUP BY или HAVING. MySQL поддерживает ссылки на псевдонимы столбцов в GROUP BY и HAVING, но я подчеркиваю, что это вызовет проблемы при переносе таких запросов в другие базы данных.

В случае сомнений используйте фактическое имя столбца:

SELECT t.lat AS latitude 
  FROM poi_table t
 WHERE t.lat < 500

Я добавил псевдоним таблицы, чтобы упростить просмотр фактического столбца с псевдонимом.

Update


Вычисленный столбец, подобный тому, который вы видите здесь:

SELECT *, 
       ( 6371*1000 * acos( cos( radians(42.3936868308) ) * cos( radians( lat ) ) * cos( radians( lon ) - radians(-72.5277256966) ) + sin( radians(42.3936868308) ) * sin( radians( lat ) ) ) ) AS distance
  FROM poi_table 
 WHERE distance < 500;

... не изменяет, что вы не можете ссылаться на псевдоним столбца в предложении WHERE. Чтобы этот запрос работал, вам нужно будет использовать:

SELECT *, 
       ( 6371*1000 * acos( cos( radians(42.3936868308) ) * cos( radians( lat ) ) * cos( radians( lon ) - radians(-72.5277256966) ) + sin( radians(42.3936868308) ) * sin( radians( lat ) ) ) ) AS distance
  FROM poi_table
 WHERE ( 6371*1000 * acos( cos( radians(42.3936868308) ) * cos( radians( lat ) ) * cos( radians( lon ) - radians(-72.5277256966) ) + sin( radians(42.3936868308) ) * sin( radians( lat ) ) ) ) < 500;

Помните, что использование функции в столбце (IE: RADIANS(lat)) сделает индекс бесполезным, если он существует в столбце.

Ответ 2

SQL Server настроен на применение фильтров до того, как он применит псевдонимы (поскольку это обычно приводит к более быстрым результатам). Вы можете сделать вложенный оператор select. Пример:

SELECT Latitude FROM 
(
    SELECT Lat AS Latitude FROM poi_table
) A
WHERE Latitude < 500

Я понимаю, что это может быть не то, что вы ищете, потому что это делает ваши запросы более многословными. Более сжатым подходом было бы сделать представление, которое обертывает вашу базовую таблицу:

CREATE VIEW vPoi_Table AS 
SELECT Lat AS Latitude FROM poi_table

Тогда вы могли бы сказать:

SELECT Latitude FROM vPoi_Table WHERE Latitude < 500

Ответ 3

Я не уверен, почему вы не можете использовать "lat", но если вы должны переименовать столбцы в производной таблице.

select latitude from (SELECT lat AS latitude FROM poi_table) p where latitude < 500

Ответ 4

Это будет работать над вашим отредактированным вопросом!

SELECT * FROM (SELECT <Column_List>,  
( 6371*1000 * acos( cos( radians(42.3936868308) ) * cos( radians( lat ) ) * cos( radians( lon ) - radians(-72.5277256966) ) + sin( radians(42.3936868308) ) * sin( radians( lat ) ) ) )  
AS distance 
FROM poi_table) TMP
WHERE distance < 500; 

Ответ 5

Порядок логической обработки оператора SELECT

Следующие шаги показывают порядок логической обработки или привязку порядок, для оператора SELECT. Этот порядок определяет, когда объекты определенные на одном этапе, становятся доступными для предложений в последующих шаги. Например, если процессор запросов может связываться с (доступом) таблицы или представления, определенные в предложении FROM, эти объекты и их столбцы становятся доступными для всех последующих этапов. Наоборот, потому что предложение SELECT является шагом 8, любые псевдонимы столбцов или производные столбцы, определенные в этом разделе, не могут быть указаны предыдущими статьи. Однако они могут ссылаться на последующие статьи, такие как предложение ORDER BY. Обратите внимание, что фактическое физическое выполнение оператор определяется процессором запросов, и порядок может меняться из этого списка.

  • С
  • ON
  • JOIN
  • WHERE
  • GROUP BY
  • С CUBE или WITH ROLLUP
  • HAVING
  • SELECT
  • DISTINCT
  • ЗАКАЗАТЬ
  • TOP

Источник: http://msdn.microsoft.com/en-us/library/ms189499%28v=sql.110%29.aspx

Ответ 6

Оба принятого ответа и Логическая обработка заказа объясняют, почему вы не могли сделать то, что предложили.

Возможное решение:

  • использовать производную таблицу (cte/subquery)
  • использовать выражение в WHERE
  • создать просмотр/вычисленный столбец

Из SQL Server 2008 вы можете использовать APPLY оператор в сочетании с Table valued Constructor:

SELECT *, s.distance
FROM poi_table 
CROSS APPLY (VALUES(6371*1000*acos(cos(radians(42.3936868308))*cos(radians(lat))*cos(radians(lon)-radians(-72.5277256966))+sin(radians(42.3936868308))*sin(radians(lat))))) AS s(distance)
WHERE distance < 500;

LiveDemo