2010-07-16 49 views
8

Tôi có một câu lệnh SQL (khá phức tạp) nơi tôi chọn dữ liệu từ nhiều bảng khác nhau và để đối phó với cấu trúc dữ liệu kế thừa xấu, tôi có một vài tùy chỉnh các cột nhận giá trị của chúng dựa trên các giá trị từ các cột khác. Hiện tại tôi đã giải quyết điều này với CASE báo cáo:Lỗi tên cột không hợp lệ trong mệnh đề WHERE, cột được chọn với CASE

SELECT 
    ..., 
    CASE channel 
     WHEN 1 THEN channel_1 
     WHEN 2 THEN channel_2 
     ... 
     ELSE 0 
    END AS ChannelValue, 
    CASE channelu 
     WHEN 1 THEN channelu_1 
     WHEN 2 THEN channelu_2 
     ... 
     ELSE '0' 
    END AS ChannelWithUnit, 
    ... 
FROM 
    ... 
--rest of statement continues with multiple joins and where/and clauses... 

tôi nhận được tất cả các kết quả tôi mong muốn khi thực hiện truy vấn trong MS SQL Server Management Studio, và các tên cột được liệt kê như tôi đã quy định tại AS khoản của tôi. Tuy nhiên, vì một lý do nào đó, tôi không được phép sử dụng các giá trị có điều kiện trong câu lệnh WHERE. Nếu tôi thêm

AND ChannelValue > Limit * p.Percentage/100 

ở phần cuối của các truy vấn, tôi nhận được một lỗi trên dòng đó nói

Msg 207, Level 16, State 1, Line 152
tên cột không hợp lệ 'ChannelValue'

Tại sao điều này không được phép? Tôi nên làm gì?

Trả lời

11

Phần duy nhất của Tuyên bố SQL, nơi nó có giá trị sử dụng một bí danh được khai báo trong danh sách SELECT là mệnh đề ORDER BY. Đối với các phần khác của truy vấn, bạn chỉ cần lặp lại toàn bộ biểu thức CASE và tin tưởng trình tối ưu hóa nhận ra nó giống nhau.

Nếu bạn đang sử dụng SQL2005 +, bạn có thể sử dụng CTE để tránh vấn đề này đôi khi giúp dễ đọc.

WITH YourQuery As 
(

SELECT 
    Limit, 
    Percentage, 
    CASE channel 
     WHEN 1 THEN channel_1 
     WHEN 2 THEN channel_2 
     ... 
     ELSE 0 
    END AS ChannelValue, 
    CASE channelu 
     WHEN 1 THEN channelu_1 
     WHEN 2 THEN channelu_2 
     ... 
     ELSE '0' 
    END AS ChannelWithUnit, 
    ... 
FROM 
) 

select ... 
FROM YourQuery WHERE 
ChannelValue > Limit * Percentage/100 
7

Bạn không thể sử dụng tên cột ChannelValue trong mệnh đề where ở cùng mức select.
Bạn sẽ phải đặt toàn bộ số này select trong truy vấn phụ.

select .... 
from 
( 
your select query 
) as innerSelect 
where ChannelValue > Limit * p.Percentage/100 
2

Bạn có thể sử dụng một CTE - một cái gì đó giống như

WITH CTE AS 
(
SELECT 
    ..., 
    CASE channel 
     WHEN 1 THEN channel_1 
     WHEN 2 THEN channel_2 
     ... 
     ELSE 0 
    END AS ChannelValue, 
    CASE channelu 
     WHEN 1 THEN channelu_1 
     WHEN 2 THEN channelu_2 
     ... 
     ELSE '0' 
    END AS ChannelWithUnit, 
    ... 
FROM 
) 
SELECT * 
FROM CTE 
WHERE ChannelValue > Limit * p.Percentage/100 
-2
-- SOMETHING FROM ADVENTURE WORKS THIS WORKS AS THE ABOVE POSTER 
--- USING 'WITH CTE AS' 
-- MY ANSWER TO A QUERY 

WITH CTE AS 
(
SELECT HE.Gender AS [GENDER], HE.HireDate AS [HIREDATE],  HE.BirthDate AS [BIRTHDATE], 
CASE 
WHEN DATEPART(YY,[BIRTHDATE]) BETWEEN 1962 AND 1970 AND [GENDER] = 'M' AND DATEPART(YY,[HIREDATE]) > 2001 THEN 'MALE' 
WHEN DATEPART(YY,[BIRTHDATE]) BETWEEN 1972 AND 1975 AND [GENDER] = 'F' AND DATEPART(YY,[HIREDATE]) BETWEEN 2001 AND 2002 THEN 'FEMALE' 
ELSE 'NOTREQUIRED' 
END AS [RESULT] 
FROM [HumanResources].[Employee] AS HE 
) 
SELECT * 
FROM CTE 
WHERE [RESULT] <> 'NOTREQUIRED' -- GOT THIS TOO WORK NO FEMALES IN RESULT 
ORDER BY [RESULT] 
Các vấn đề liên quan