SQL 服务器 'AS' 别名意外的语法
SQL Server 'AS' alias unexpected syntax
我今天遇到了关注T-SQL的人:
select c from (select 1 union all select 1) as d(c)
产生以下结果:
c
-----------
1
1
让我感到困惑的部分是 d(c)
在试图理解发生了什么时,我将 T-SQL 修改为:
select c, b from (select 1, 2 union all select 3, 4) m(c, b)
产生以下结果:
c b
----------- -----------
1 2
3 4
很明显 d & m 是 table 引用,而括号 c & b 是对列的引用。
我没能在 msdn 上找到相关文档,但很好奇 if
- 你知道这样的语法吗?
- 什么是有用的用例场景?
select c from (select 1 union all select 1) as d(c)
与
相同
select c from (select 1 as c union all select 1) as d
在第一个查询中,您没有在子查询中命名列,而是在子查询之外命名它们,
在第二个查询中,您在子查询中命名列
如果您这样尝试(不命名子查询中的列)
select c from (select 1 union all select 1) as d
你会得到以下错误
No column name was specified for column 1 of 'd'
至于用法,有的喜欢写第一种方法,有的喜欢第二种方法,随便你怎么写。都一样
您已经有评论指出派生的 table 是如何工作的文档,但不是为了回答您有关此功能的有用用例的问题。
就我个人而言,每当我想创建一组将在您的语句中广泛使用的可寻址值时,或者当我出于任何原因想要复制行时,我都发现此功能很有用。
可寻址值的一个例子是以下更复杂的版本,其中 v
派生的 table 中的计算值可以通过更合理的名称多次使用,而不是难以理解的重复计算:
select p.ProductName
,p.PackPricePlusVAT - v.PackCost as GrossRevenue
,etc
from dbo.Products as p
cross apply(values(p.UnitsPerPack * p.UnitCost
,p.UnitPrice * p.UnitsPerPack * 1.2
,etc
)
) as v(PackCost
,PackPricePlusVAT
,etc
)
能够复制行的一个例子是创建一个用于验证数据的异常报告,它将为 dbo.Product
行满足的每个 DataError
条件输出一行:
select p.ProductName
,e.DataError
from dbo.Products as p
cross apply(values('Missing Units Per Pack'
,case when p.SoldInPacks = 1 and isnull(p.UnitsPerPack,0) < 1 then 1 end
)
,('Unusual Price'
,case when p.Price > (p.UnitsPerPack * p.UnitCost) * 2 then 1 end
)
,(etc)
) as e(DataError
,ErrorFlag
)
where e.ErrorFlag = 1
如果您能理解这两个脚本的作用,您应该会找到大量示例,说明在哪些地方能够生成额外的值或额外的数据行会非常有帮助。
观察:使用 table 构造函数 values
无法命名列,这使得必须在 table 别名之后使用列命名:
select * from
(values
(1,2) -- can't give a column name here
,(3,4)
) as tableName(column1,column2) -- gotta do it here
我今天遇到了关注T-SQL的人:
select c from (select 1 union all select 1) as d(c)
产生以下结果:
c
-----------
1
1
让我感到困惑的部分是 d(c)
在试图理解发生了什么时,我将 T-SQL 修改为:
select c, b from (select 1, 2 union all select 3, 4) m(c, b)
产生以下结果:
c b
----------- -----------
1 2
3 4
很明显 d & m 是 table 引用,而括号 c & b 是对列的引用。 我没能在 msdn 上找到相关文档,但很好奇 if
- 你知道这样的语法吗?
- 什么是有用的用例场景?
select c from (select 1 union all select 1) as d(c)
与
相同select c from (select 1 as c union all select 1) as d
在第一个查询中,您没有在子查询中命名列,而是在子查询之外命名它们,
在第二个查询中,您在子查询中命名列
如果您这样尝试(不命名子查询中的列)
select c from (select 1 union all select 1) as d
你会得到以下错误
No column name was specified for column 1 of 'd'
至于用法,有的喜欢写第一种方法,有的喜欢第二种方法,随便你怎么写。都一样
您已经有评论指出派生的 table 是如何工作的文档,但不是为了回答您有关此功能的有用用例的问题。
就我个人而言,每当我想创建一组将在您的语句中广泛使用的可寻址值时,或者当我出于任何原因想要复制行时,我都发现此功能很有用。
可寻址值的一个例子是以下更复杂的版本,其中 v
派生的 table 中的计算值可以通过更合理的名称多次使用,而不是难以理解的重复计算:
select p.ProductName
,p.PackPricePlusVAT - v.PackCost as GrossRevenue
,etc
from dbo.Products as p
cross apply(values(p.UnitsPerPack * p.UnitCost
,p.UnitPrice * p.UnitsPerPack * 1.2
,etc
)
) as v(PackCost
,PackPricePlusVAT
,etc
)
能够复制行的一个例子是创建一个用于验证数据的异常报告,它将为 dbo.Product
行满足的每个 DataError
条件输出一行:
select p.ProductName
,e.DataError
from dbo.Products as p
cross apply(values('Missing Units Per Pack'
,case when p.SoldInPacks = 1 and isnull(p.UnitsPerPack,0) < 1 then 1 end
)
,('Unusual Price'
,case when p.Price > (p.UnitsPerPack * p.UnitCost) * 2 then 1 end
)
,(etc)
) as e(DataError
,ErrorFlag
)
where e.ErrorFlag = 1
如果您能理解这两个脚本的作用,您应该会找到大量示例,说明在哪些地方能够生成额外的值或额外的数据行会非常有帮助。
观察:使用 table 构造函数 values
无法命名列,这使得必须在 table 别名之后使用列命名:
select * from
(values
(1,2) -- can't give a column name here
,(3,4)
) as tableName(column1,column2) -- gotta do it here