SQL选择虚拟列引用虚拟列

时间:2018-03-28 19:07:49

标签: sql sql-server tsql

我甚至不知道如何正确地表达我的问题,但基本上我在Azure SQL Server(Transact-SQL)中有这个Select语句:

这不起作用:

SELECT 
  Person.PersonID,
  Person.DisplayName, 
  VacationRequest.VacationYear,
  SUM(code for VacApp) AS VacApp,
  SUM(code for VacPen) AS VacPen,
  (VacApp + VacPen) AS VacBal
FROM Person
INNER JOIN VacationRequest ON Person.PersonID = VacationRequest.PersonID
GROUP BY Person.PersonID,Person.DisplayName, VacationRequest.VacationYear;

一切正常,除了最后一栏VacBal我得到SQL错误:

"Failed to execute query. Error: Invalid column name 'VacApp'. Invalid column name 'VacPen'." 

如果我将我的陈述改为不使用VacApp和VacPen并将其SUM函数放在他们的位置,那么它是有效的。然而,由于我的SUM()函数非常冗长而复杂,因此SQL代码变得混乱。

此作品

SELECT 
  Person.PersonID,
  Person.DisplayName, 
  VacationRequest.VacationYear,
  SUM(code for VacApp) AS VacApp,
  SUM(code for VacPen) AS VacPen,
  (SUM(code for VacApp) + SUM(code for VacPen)) AS VacBal
FROM Person
INNER JOIN VacationRequest ON Person.PersonID = VacationRequest.PersonID
GROUP BY Person.PersonID,Person.DisplayName, VacationRequest.VacationYear;

我可以使用这个,但几年之后我很难理解我在这里做了多少。此外,如果我为VacApp切换SUM功能,我需要记住将其复制粘贴到VacBal。

有没有办法简化这个,比如使用(VacApp + VacPen)AS VacBal?
那些在SELECT语句中创建的列如何调用(使用SUM等函数创建的列,或者将几列合并为一列)?我称之为虚拟列,但我确定这不是正确的命名。

2 个答案:

答案 0 :(得分:0)

您可以使用子查询/ CTE ::

WITH cte AS (
  SELECT 
    Person.PersonID,
    Person.DisplayName, 
    VacationRequest.VacationYear,
    SUM(code for VacApp) AS VacApp,
    SUM(code for VacPen) AS VacPen
  FROM Person
  INNER JOIN VacationRequest ON Person.PersonID = VacationRequest.PersonID
  GROUP BY Person.PersonID,Person.DisplayName, VacationRequest.VacationYear
)
SELECT *,  (VacApp + VacPen) AS VacBal
FROM  cte;

或使用CROSS / OUTER APPLY:

  SELECT 
  Person.PersonID,
  Person.DisplayName, 
  VacationRequest.VacationYear,
  SUM(s1.col_name) AS VacApp,
  SUM(s2.col_name) AS VacPen,
  (SUM(s1.col_name) + SUM(s2.col_name)) AS VacBal
FROM Person
INNER JOIN VacationRequest ON Person.PersonID = VacationRequest.PersonID
OUTER APPLY (code for VAcApp) s1
OUTER APPLY (code for VacPen) s2
GROUP BY Person.PersonID,Person.DisplayName, VacationRequest.VacationYear;

答案 1 :(得分:0)

如果要添加值,则需要子查询或CTE:

SELECT vpr.*,  (VacApp + VacPen) AS VacBal
FROM (SELECT p.PersonID, p.DisplayName,  vr.VacationYear,
             SUM(code for VacApp) AS VacApp,
             SUM(code for VacPen) AS VacPen
      FROM Person p JOIN
           VacationRequest vr
           ON p.PersonID = vr.PersonID
      GROUP BY p.PersonID, p.DisplayName, vr.VacationYear
     ) vrp;

请注意,表别名使查询更容易编写和读取。