可以在视图中使用别名列进行其他列中的计算吗?

时间:2015-10-15 13:08:51

标签: sql sql-server sql-server-2008-r2

CREATE VIEW dbo.myview1 As
SELECT 
a.Id , 
a.Name , 
a.Age , 
CASE 
WHEN b.PmtSched ='Monthly'      THEN 12
WHEN b.PmtSched ='Quarterly'    THEN 4
WHEN b.PmtSched ='Semi-Annual'  THEN 2
WHEN b.PmtSched ='Annually'     THEN 1
ELSE 12
END AS ABC,
SUM(a.Amount) *50 as TotalAmount ,
(a.AmtSpent - TotalAmount) * ABC as TOTALSPENDS 

FROM dbo.User a join dbo.Details b on a.Id = b.Id

这里ABC和TotalAmount是别名列,需要在视图中用于计算,我无法使用它们。如何实现这一点?我们有什么方法可以做到这一点或者我们不能解决?请帮助。

3 个答案:

答案 0 :(得分:5)

解决问题的简单方法是重复表达式,使用子查询或使用CTE。

但是,更智能的方法是为付款计划添加参考表。这看起来像是:

create table PaymentSchedules (
    PaymentScheduleId int identity(1, 1) primary key,
    ScheduleName varchar(255),
    FrequencyPerYear float  -- this could be less often than once per year
);

然后视图看起来像:

CREATE VIEW dbo.myview1 As
    SELECT a.Id, a.Name, a.Age, ps.FrequencyPerYear, 
           SUM(a.Amount) * 50 as TotalAmount,
           (a.AmtSpent - SUM(a.Amount) * 50) * ps.FrequencyPerYear as TOTALSPENDS 
    FROM dbo.User a join
         dbo.Details b
         on a.Id = b.Id join
         dbo.PaymentSchedules ps
         on ps.PaymentScheduleId = a.PamentScheduleId;

答案 1 :(得分:1)

是的,您可以使用它,既不需要子查询,也不需要CTE。这是一个简单的CROSS APPLY。它非常优雅,不会影响可读性。如果您需要更多信息,请阅读here

请看这个例子:

CREATE VIEW dbo.myview1
AS
SELECT A.Id
    , A.Name
    , A.Age
    , SUM(A.Amount) * 50 AS TotalAmount
    , (A.AmtSpent - TotalAmount) * T.ABC AS TotalSpends
FROM dbo.[User] AS A
CROSS APPLY (
    SELECT CASE B.PmtSched
            WHEN 'Monthly' THEN 12
            WHEN 'Quarterly' THEN 4
            WHEN 'Semi-Annual' THEN 2
            WHEN 'Annually' THEN 1
            ELSE 12
        END) AS T(ABC)
INNER JOIN dbo.Details AS B
    ON A.Id = B.Id;

答案 2 :(得分:1)

简单回答“否”

如果没有subquery,就无法做到这一点。

您需要使用CTE

  

以下查询将帮助您获得所需内容。

;WITH Amount
(
SELECT a.Id,a.NAME,a.Age,a.AmtSpent,
            CASE WHEN b.PmtSched ='Monthly'      THEN 12
                 WHEN b.PmtSched ='Quarterly'    THEN 4
                 WHEN b.PmtSched ='Semi-Annual'  THEN 2
                 WHEN b.PmtSched ='Annually'     THEN 1
            ELSE 12
            END AS ABC
           ,SUM(a.Amount) * 50 AS TotalAmount
    FROM 
        dbo.[User] a
    INNER JOIN
        dbo.Details b ON a.Id = b.Id
    GROUP BY id, NAME, age, abc, a.AmtSpent, TotalAmount
)
  

现在您可以调用这些别名进行计算。

SELECT id,NAME,age,abc,(a.AmtSpent - TotalAmount) * ABC AS TOTALSPENDS FROM Amount