2013-04-23 33 views
29

Khi tôi cố gắng thực hiện các đoạn mã sau trong SQL Server 2005 tôi nhận được lỗiLàm thế nào để sử dụng tên bí danh cột trong mệnh đề where trong SQL Server

tên cột không hợp lệ DistanceFromAddress

Mã số:

select 
    SQRT(POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
    POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2)) * 62.1371192 AS DistanceFromAddress 
from 
    tblProgram 
where 
    DistanceFromAddress < 2 

Tôi nhận được giá trị đúng bằng cách sử dụng câu lệnh chọn, nhưng khi tôi cố kiểm tra điều kiện where DistanceFromAddress < 2 Tôi gặp lỗi.

Tôi làm cách nào để giải quyết vấn đề này?

+0

Bản sao có thể có của [Tham khảo bí danh cột trong một điều khoản WHERE] (https://stackoverflow.com/questions/8370114/referring-to-a-column-alias-in-a-where-clause) – Vadzim

+0

I quess, chỉ cần nhân đôi biểu thức đó mệnh đề 'WHERE' sẽ đưa ra kế hoạch tốt hơn so với các câu hỏi con được đề xuất trong các câu trả lời ở đây. – Vadzim

Trả lời

35

Bạn không thể sử dụng cột có răng cưa trong mệnh đề WHERE. Bạn có thể thử sử dụng một bảng có nguồn gốc.Có lẽ một cái gì đó như thế này (xin lỗi, không được thử nghiệm):

SELECT * FROM 
(SELECT SQRT(POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2)) * 62.1371192 
AS DistanceFromAddress from tblProgram) mytable 
WHERE DistanceFromAddress < 2 
24

Điều khoản WHERE được xử lý trước mệnh đề SELECT (*) và do đó, các bí danh không khả dụng. Di chuyển sang sử dụng một subquery hoặc CTE - đây là một CTE:

; with Distances as (
    select SQRT(POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2)) * 62.1371192 
AS DistanceFromAddress 
    from tblProgram 
) 
select * from Distances where DistanceFromAddress < 2 

(*) - tốt, hệ thống có thể tự do xếp lại thứ tự các hoạt động như họ thấy phù hợp, miễn là kết quả là "như thể "câu lệnh SQL đã được xử lý trong một số logical order nhất định. Tất nhiên, nơi tất cả điều này sai với SQL Server là nơi nó produces errors vì các vấn đề chuyển đổi trong mệnh đề SELECT cho các hàng/giá trị cần được loại bỏ theo mệnh đề WHERE.

1
select 
    SQRT(
    POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
    POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2) 
) * 62.1371192 AS DistanceFromAddress 
from tblProgram 
having DistanceFromAddress < 2 

có thể hoạt động (mặc dù tôi nghĩ không, không có nhóm theo điều khoản).

Vấn đề là bạn chỉ có thể sử dụng tên trong phạm vi (các) bảng bạn chọn bên trong mệnh đề where. Where là một bộ lọc trước lọc ra các hàng trước khi chúng được chọn, vì vậy các biểu thức như thế này trong định nghĩa trường chưa được thực hiện và các bí danh không có sẵn.

Điều khoản Having hoạt động như bộ lọc bài đăng sau khi nhóm và có thể sử dụng bí danh từ truy vấn, mặc dù tôi e rằng bạn sẽ cần phải có mệnh đề group by thực tế (không chắc chắn).

Cách khác là chọn một phụ (bảng có nguồn gốc hoặc chọn trong lựa chọn), trước tiên bạn chọn khoảng cách cho mỗi hàng và sau đó chỉ chọn khoảng cách có liên quan từ các kết quả đó. Điều này sẽ hoạt động:

select d.DistanceFromAddress 
from 
    (select 
    SQRT(
     POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
     POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2) 
    ) * 62.1371192 AS DistanceFromAddress 
    from tblProgram) d 
where d.DistanceFromAddress < 2 

Hoặc bạn có thể lặp lại biểu thức. Điều này làm cho truy vấn của bạn khó duy trì hơn, nhưng trong một số trường hợp, điều này có thể phù hợp với bạn. Ví dụ: nếu bạn không muốn trả lại khoảng cách thực tế, nhưng chỉ, ví dụ, tên của điểm quan tâm ở khoảng cách đó. Trong trường hợp đó, bạn cần phải có biểu thức chỉ trong mệnh đề where, trong trường hợp đó, đối số bảo trì đã biến mất và giải pháp này là giải pháp thay thế hoàn hảo.

select 
    tblProgram.POIname 
    /* Only if you need to return the actual value 
    , SQRT(
    POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
    POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2) 
) * 62.1371192 AS DistanceFromAddress */ 
from tblProgram 
where 
    -- Use this if you only want to filter by the value. 
    SQRT(
    POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
    POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2) 
) * 62.1371192 < 2 
0

Tôi nghĩ bạn chỉ có thể sử dụng AS để hiển thị giá trị cuối cùng. Để thực hiện so sánh, lựa chọn phải được trả về từ một câu lệnh chọn khác bên trong nó.

Giống như:

SELECT a.disfromaddr FROM 
(SELECT SQRT(POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2)) * 62.1371192 
AS DistanceFromAddress FROM tblProgram) 
a WHERE a.disfromaddr < 2 

Bạn có thể thử này.

Các vấn đề liên quan