2012-10-23 30 views
10

thể trùng lặp:
Referring to a Column Alias in a WHERE ClauseLàm cách nào để sử dụng bí danh trong mệnh đề where?

SELECT 
Trade.TradeId, 
Isnull(Securities.SecurityType,'Other') SecurityType, 
TableName, 
CASE 
WHEN 
SecurityTrade.SecurityId IS NOT NULL 
THEN 
SecurityTrade.SecurityId 
ELSE 
Trade.SecurityId 
END AS PricingSecurityID, 
sum(Trade.Quantity)OVER(Partition by Securities.SecurityType, SecurityTrade.SecurityId,Trade.Price, Buy,Long) as sumQuantity, 
--added porfolio id for Getsumofqantity 
Trade.PortfolioId, 

Trade.Price, 
case 
when (Buy = 1 and Long = 1) then 1 
when (Buy = 0 and Long = 0) then 1 
else 0 
end Position 
from 
Fireball_Reporting..Trade 

where porfolioid =5 and Position =1 

tôi muốn sử dụng vị trí = 1 trong mệnh đề where của tôi đó là một bí danh của trường hợp

case 
when (Buy = 1 and Long = 1) then 1 
when (Buy = 0 and Long = 0) then 1 
else 0 
end Position 

Làm thế nào tôi có thể sử dụng nó trong mệnh đề where?

Tôi đã cố gắng sử dụng trực tiếp mà tuyên bố CASE trong mệnh đề where nhưng thất bại hãy giúp tôi

WHERE Trade.SecurityId = @SecurityId AND PortfolioId = @GHPortfolioID AND 
       (case when (Buy = 1 and Long = 1) then 1 when (Buy = 0 and Long = 0) then 1 else 0 end Position = 1) 
+0

Bạn không thể trừ khi bạn thêm một lựa chọn khác và kiểm tra postion = 1 trên truy vấn bên ngoài. –

+0

Bạn đang sử dụng ngôn ngữ SQL nào? – StingyJack

+0

T SQL trong máy chủ sql 2008 – Neo

Trả lời

31

Chuẩn SQL không cho phép tham chiếu đến các bí danh cột trong một mệnh đề WHERE. Hạn chế này được áp dụng vì khi mệnh đề WHERE được đánh giá, giá trị cột có thể chưa được xác định.

Taken from MySQL Doc

column_alias có thể được sử dụng trong một mệnh đề ORDER BY, nhưng nó không thể được sử dụng trong một đề WHERE, GROUP BY, hoặc HAVING khoản.

Taken from the MSSQL Doc

+3

'Lấy từ MySQL Doc' trên một câu trả lời được gắn thẻ là 'sql-server'? – MatBailie

13

Bạn có thể không, không trực tiếp.

Nếu bạn bọc toàn bộ truy vấn trong truy vấn phụ, tuy nhiên, nó hoạt động tốt.

SELECT 
    * 
FROM 
(
    SELECT 
    Trade.TradeId, 
    Isnull(Securities.SecurityType,'Other') SecurityType, 
    TableName, 
    CASE 
     WHEN SecurityTrade.SecurityId IS NOT NULL THEN SecurityTrade.SecurityId 
               ELSE Trade.SecurityId 
    END AS PricingSecurityID, 
    sum(Trade.Quantity)OVER(Partition by Securities.SecurityType, 
    SecurityTrade.SecurityId,Trade.Price, Buy,Long) as sumQuantity, 
    --added porfolio id for Getsumofqantity 
    Trade.PortfolioId, 
    Trade.Price, 
    case 
     when (Buy = 1 and Long = 1) then 1 
     when (Buy = 0 and Long = 0) then 1 
            else 0 
    end Position 
    from 
    Fireball_Reporting..Trade 
    where 
    porfolioid = 5 
) 
    AS data 
WHERE 
    Position = 1 

Điều này có nghĩa là bạn không cần phải lặp lại mệnh đề CASE trong mệnh đề WHERE. (Duy trì và DRY).

Nó cũng là một cấu trúc cho phép optimizer để hành xử như thể bạn chỉ đơn giản lặp đi lặp lại chính mình trong mệnh đề WHERE.

Nó cũng rất dễ dàng với các RDBMS khác.


Trong SQL Server, sau đó bạn cũng có tùy chọn khác ...

SELECT 
    Trade.TradeId, 
    Isnull(Securities.SecurityType,'Other') SecurityType, 
    TableName, 
    CASE 
    WHEN SecurityTrade.SecurityId IS NOT NULL THEN SecurityTrade.SecurityId 
               ELSE Trade.SecurityId 
    END AS PricingSecurityID, 
    sum(Trade.Quantity)OVER(Partition by Securities.SecurityType, 
    SecurityTrade.SecurityId,Trade.Price, Buy,Long) as sumQuantity, 
    --added porfolio id for Getsumofqantity 
    Trade.PortfolioId, 
    Trade.Price, 
    position.val AS Position 
from 
    Fireball_Reporting..Trade 
CROSS APPLY 
(
    SELECT 
    case 
     when (Buy = 1 and Long = 1) then 1 
     when (Buy = 0 and Long = 0) then 1 
            else 0 
    end AS val 
) 
    AS position 
where 
    porfolioid = 5 
    AND position.val = 1 
+0

Câu trả lời của Juergen và câu trả lời của bạn liên quan đến thực tế là ".. khi mệnh đề WHERE được đánh giá, giá trị cột có thể chưa được xác định." nhưng vì bạn đang sử dụng truy vấn phụ sẽ có. – Mukus

5

Bạn có thể không trực tiếp làm điều này ... nhưng bạn có thể quấn thêm chọn xung quanh nó tất cả và sử dụng mệnh đề where:

select * from 
    ( SELECT 
    Trade.TradeId, 
    Isnull(Securities.SecurityType,'Other') SecurityType, 
    TableName, 
    CASE 
    WHEN 
    SecurityTrade.SecurityId IS NOT NULL 
    THEN 
    SecurityTrade.SecurityId 
    ELSE 
    Trade.SecurityId 
    END AS PricingSecurityID, 
    sum(Trade.Quantity)OVER(Partition by Securities.SecurityType,  SecurityTrade.SecurityId,Trade.Price, Buy,Long) as sumQuantity, 
    --added porfolio id for Getsumofqantity 
    Trade.PortfolioId, 
    Trade.Price, 
    case 
    when (Buy = 1 and Long = 1) then 1 
    when (Buy = 0 and Long = 0) then 1 
    else 0 
    end Position 
    from 
    Fireball_Reporting..Trade 
    where porfolioid =5 and Position =1 
    )x 
    where x.position = 1 
0

tôi có thể bị thiếu một cái gì đó nhưng chắc chắn điều này sẽ bao gồm nó:

WHERE (Buy = 1 and Long = 1) OR (Buy = 0 and Long = 0)

+1

. Nhưng "Don't Repeat Yourself" (DRY) là một nguyên tắc cơ bản hỗ trợ bảo trì và gỡ lỗi * rất nhiều *. Vì vậy, có thể tham khảo một phép tính nhiều lần là rất mong muốn. – MatBailie

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