union/union all 查询中的别名 - SQL Server

Aro*_*mal 5 t-sql sql-server

我有一个简单的sql语句如下

情况1:

select 1 as a 
union  
select 2 as a
Run Code Online (Sandbox Code Playgroud)

输出:此案例按预期工作

在此输入图像描述

案例2:

select 1 as a 
union  
select 2 as b
Run Code Online (Sandbox Code Playgroud)

输出:虽然我的第二个选择中的别名是“b”,但它仍然显示别名“a”。

为什么它不能从第二个 select 语句中获取别名?

我们如何让 sql 从第二个 select 查询中选择别名?

在此输入图像描述

案例3:

select 1 
union  
select 2 as b
Run Code Online (Sandbox Code Playgroud)

输出:即使我上面的第一个 select 语句没有任何别名,但第二个 select 语句仍然有,为什么结果仍然显示“无列名”?

在此输入图像描述

Jor*_*pos 5

让我们尝试在这里教一些有用的东西。这不仅仅是It's because that's how it is。有一个模式定义规定了 SQL 语言的规则,称为 SQL ANSI。您可以在此处查看此定义的时间表:数据库管理 - ANSI SQL 标准和指南

这个定义背后的原因很容易理解。由于UNION操作将两个查询的结果转换为一个,因此必须应用一些规则,例如字段名称的定义、字段的类型(按照选择的顺序)等。

别名部分仅适用于第一个,因为数据库无法识别联合操作中哪一列是正确的,因为每个结果将得到一行:

 select 1 as a
 UNION
 select 2
Run Code Online (Sandbox Code Playgroud)

这将导致:

 a
 1
 2
Run Code Online (Sandbox Code Playgroud)

由于它显示为 ROWS,如果它为 UNION 堆栈中的每个 SQL 命名每一列,数据库将如何工作?

 -a
  1
 -b
  2
Run Code Online (Sandbox Code Playgroud)

这就是应用第一个查询别名规则的原因。

SQL ANSI 文档不是免费的,但如果您深入挖掘,您可能会在 PDF 中找到它的早期版本。祝你好运:)(提示:我的个人资料中有一个答案,其中包含工作链接;))


Rad*_*hiu 2

您可以将所有内容包装在一个列中SELECT,并用您想要的内容为该列指定别名。

select a as [b] -- just alias it here with whatever you want
from (
    select 1 as a 
    union  
    select 2 as b
    ...) result_set
Run Code Online (Sandbox Code Playgroud)

但正如 @Will 所说,这就是事实,无法改变。

或者:

只需确保您在顶部使用带有“别名”的查询,并且使用包含您拥有的其他查询/值的UNION单个语句。SELECT

select 2 as b

union

select a
from (
    select 1 as a
    union
    select 3 as c
    union
    ... ) result_set
Run Code Online (Sandbox Code Playgroud)