2010-02-22 38 views
9

Tôi đang sử dụng SqlServer 2005 và tôi có một cột mà tôi đã đặt tên.Bộ lọc dựa trên tên cột bí danh

Truy vấn là một cái gì đó như:

SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias 
FROM myTable 
WHERE myAlias IS NOT NULL 

Tuy nhiên, điều này mang lại cho tôi những lỗi:

"Invalid column name 'myAlias'."

Có cách nào để làm được việc này? Trong quá khứ, tôi đã bao gồm định nghĩa cột trong phần WHERE hoặc HAVING, nhưng chúng hầu hết là đơn giản, IE COUNT (*) hoặc bất kỳ thứ gì. Tôi có thể bao gồm định nghĩa toàn bộ cột trong truy vấn đặc biệt này, nhưng nếu vì lý do nào đó tôi cần thực hiện điều này trong truy vấn sản xuất, tôi chỉ muốn định nghĩa cột một lần để không phải cập nhật cả hai (và quên làm một lúc nào đó)

Trả lời

11

Bạn không có thể tham khảo các bí danh trong một mệnh đề where như thế ... bạn có phải lặp lại trong các CASE trong WHERE, hoặc bạn có thể sử dụng một subquery như thế này:

SELECT id, myAlias 
FROM 
(
    SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias 
    FROM myTable 
) data 
WHERE myAlias IS NOT NULL 
+2

Than ôi, tôi hy vọng nó sẽ đơn giản hơn. –

+0

Tôi cũng vậy, nên có một giải pháp chung chung hơn thực sự –

1

đặt trường hợp vào vị trí. SQL Server sẽ đủ thông minh để chỉ đánh giá nó một thời gian, do đó bạn không thực sự sao chép mã:

SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias 
FROM myTable 
WHERE CASE WHEN <snip extensive column definition> END IS NOT NULL 

bạn có thể bọc nó trong một bảng có nguồn gốc:

SELECT dt.id, dt.myAlias 
    FROM (
      SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias 
      FROM myTable 
     ) dt 
    WHERE dt.myAlias IS NOT NULL 

Tuy nhiên, tôi cố gắng tránh các bảng có nguồn gốc mà không có một WHERE hạn chế. Bạn có thể thử nó để xem nó có ảnh hưởng đến hiệu suất hay không.

+0

@KM, tôi lo lắng nhiều hơn về việc cập nhật một TRƯỜNG HỢP và quên cập nhật thứ hai. Giống như bạn tôi mong đợi rằng SQL Server sẽ tối ưu hóa cuộc gọi thứ hai –

1

Đặt cùng tuyên bố CASE trong mệnh đề WHERE:

SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias 
FROM myTable 
WHERE CASE WHEN <snip extensive column definition> END IS NOT NULL 

EDIT

lựa chọn khác là tổ truy vấn:

SELECT id, myAlias 
FROM (
    SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias 
    FROM myTable 
) AS subTable 
WHERE myAlias IS NOT NULL 

(Edit: loại bỏ HAVING tùy chọn, vì điều này không chính xác (nhờ @OMG Ponies))

+0

Bạn hoàn toàn chính xác - Tôi sẽ xóa phần đó. – Codesleuth

+0

@OMG ngựa: hãy thử trong SQL Server. mà không có nhóm, nó giống như WHERE khá nhiều ... http://msdn.microsoft.com/en-us/library/ms180199%28SQL.90%29.aspx Vì vậy, giải pháp của Codeleuth có thể đã đúng mà không sử dụng nguồn gốc bảng – gbn

+0

@gbn: Lạ lùng! Chắc chắn sẽ cố gắng khi tôi làm việc. Xin lỗi về điều đó, Codesleuth. –

5

Sử dụng CTEs cũng là một tùy chọn:

;with cte (id, myAlias) 
as (select id, case when <snip extensive column definition> end as myAlias 
     from myTable) 
select id, myAlias 
    from cte 
    where myAlias is not null 
+0

Cảm ơn Philip, tôi không quen thuộc với CTE, có vẻ như đó là một chế độ xem tạm thời. Đó có phải là một tuyên bố công bằng không? –

+0

@nathan koop: có, giống như các giải pháp bảng dẫn xuất được cung cấp quá ... – gbn

+0

Cảm ơn tôi sẽ xem xét nó –

0

Tôi đã tạo bảng tạm thời để thực hiện việc này. Đây là một số mã giả để cung cấp cho bạn một ý tưởng. Điều này làm việc với một sự tham gia phức tạp, tôi chỉ hiển thị một trường hợp đơn giản ở đây.

--Check to see if the temp table already exists 
If(OBJECT_ID('tempdb..#TempTable') Is Not Null) 
Begin 
    DROP TABLE #TempTable 
End 

--Create the temp table 
CREATE TABLE #TempTable 
{ 
    YourValues NVARCHAR(100) 
} 

--Insert your data into the temp table   
INSERT INTO #TempTable(YourValues) 
SELECT yt.Column1 as YourColumnOne FROM YourTable yt 

--Query the filtered data based on the aliased column  
SELECT * 
FROM #TempTable 
WHERE YourColumnOne = 'DataToFilterOn' 

--Don't forget to remove the temp table 
DROP TABLE #TempTable 
Các vấn đề liên quan