由表达式定义的列在同一个 Select 中再次使用

问题描述 投票:0回答:2

我在 select 语句中使用了一个表达式来定义 open_bal ,并且 在相同选择中的下面的 case 表达式中使用它。
这在 Sybase 任何地方都可以正常工作,但在 SQL Server 中不起作用。

    SELECT account.acno,   
        account.name,   
        sum( isnull(withdrawl,0) - isnull(deposit,0)) as open_bal,   
        (case when open_bal = 0 then 0 else 1 end) as open_flag
    from account  where....

我在 select 语句中使用 open_bal 作为动态列,并在同一 select 中的下面的 case 语句中使用。
这在 Sybase 任何地方都可以正常工作,但在 SQL Server 中不起作用。

对此的一个解决方案是在两个地方调用 Sum (isnull(.... 函数) 两次(如下所示),这会增加执行时间,这不是理想的解决方案

SELECT account.acno,   
    account.name,   
    sum( isnull(withdrawl,0) - isnull(deposit,0)) as open_bal,   
    (case when sum( isnull(withdrawl,0) - isnull(deposit,0)) = 0 then 0 else 1 end) as open_flag
from account  where....
sql sql-server sql-server-2012
2个回答
1
投票

使用汤姆的建议,类似这样的东西?

--CTE 
WITH cte_Open_bal
AS (
    SELECT account.acno,   
        account.name,   
        sum( isnull(withdrawl,0) - isnull(deposit,0)) as open_bal  
    FROM account  
    WHERE....
    )
SELECT c.acno
    ,c.name
    ,c.open_bal
    ,(CASE WHEN c.open_bal = 0 THEN 0 ELSE 1 END) AS open_flag
FROM cte_Open_bal c;

--Subquery
SELECT c.acno
    ,c.name
    ,c.open_bal
    ,(CASE WHEN c.open_bal = 0 THEN 0 ELSE 1 END) AS open_flag
FROM (
    SELECT account.acno,   
        account.name,   
        sum( isnull(withdrawl,0) - isnull(deposit,0)) as open_bal  
    FROM account  
    WHERE....
    ) c;

0
投票

另一个选项是

CROSS APPLY
,它允许您堆叠和/或重用派生值。

只是为了好玩,我扔了

abs(sign(sum(B.openbal)))
......显然,如果你愿意,你可以使用
case

示例

SELECT account.acno
      ,account.name
      ,open_bal  = sum( B.openbal )
      ,open_flag = abs(sign(sum(B.openbal)))
from account  
Cross Apply ( values ( isnull(withdrawl,0) - isnull(deposit,0) ) ) B(openbal) 
where....
Group By account.acno,account.name
© www.soinside.com 2019 - 2024. All rights reserved.