在SQL Server中运行此查询时
SELECT custid AAA, companyname AAA
FROM Sales.Customers
WHERE country = 'USA'
运行正常。但现在结果集具有重复的列名称(AAA)。为什么SQL服务器允许这种情况发生?如果应用程序需要引用列名,应用程序如何工作?我知道如果你把这个查询作为派生表SQL将阻止你。像
SELECT *
FROM
(SELECT custid AAA, companyname AAA
FROM Sales.Customers
WHERE country = 'USA') BBB
SQL Server报告错误:
'BBB'
多次指定了'AAA'列
这背后的逻辑是什么?
谢谢
答案 0 :(得分:2)
此问题的原因是:
第一次查询
SELECT custid AAA, companyname AAA
FROM Sales.Customers
WHERE country = 'USA'
在这里,您在输出时分配列别名,因此AAA
在返回结果时附加为列名(实际上是别名),但我猜您只会看到第一列{{1} 1}}其他将被删除,因为在进一步参考期间可能存在冲突。所以在这里你没有得到错误。
AAA
这里出现错误,因为您正在从名为SELECT * FROM (
SELECT custid AAA, companyname AAA
FROM Sales.Customers
WHERE country = 'USA') BBB
的{{3}}中选择记录,此处内部查询(内联视图)被视为表(对于您的BBB
语句) ,而且我们知道 - 基本上Table不能有多个相同的列名,因为你得到BBB有多个SELECT * FROM
列的错误。
答案 1 :(得分:2)
这可以通过理解查询执行的不同逻辑阶段的执行顺序来解释。 Query Execution Order MSDN
在SQL Server中,顺序为FROM > WHERE > SELECT
,即执行第一个FROM子句,然后执行WHERE子句,最后一个是SELECT列表。
现在,在第一个查询中,将获取表Sales.Customers中的所有匹配行,然后提取SELECT
列表中指定的列,然后应用别名。
在第二个查询中,内部查询作为第一个查询成功执行,但是当外部查询的FROM
子句尝试从内部查询返回的结果集中获取列时,它会找到重复的列并抛出错误。
答案 2 :(得分:1)
您将两个相同的别名名称提供给不同的列,这些列将在一个表中呈现为重复列。
这就是它给出错误的原因。
如果您将其设为不同的别名,则不会发生错误。请尝试并让我知道它是否有效。
答案 3 :(得分:0)
感谢你们所有人的回复。 我同意Nikhil Butani的看法。这是我的想法。
我们都知道有关表列的基本规则 1.必须有一个名字 2.名称必须是唯一的。
我提供的第一个查询
SELECT custid AAA,companyname AAA 来自Sales.Customers WHERE country ='USA'
实际上是一个结果。它不是表格,因此不需要遵守规则。但是当我在第二个查询中将它用作派生表时,它必须是一个有效的表。列规则适用。
这是更有趣的事情。更改查询1,如下所示
SELECT custid AAA, companyname + ''
FROM Sales.Customers
WHERE country = 'USA'
它使第二列没有名称,因为它是一个表达式。运行正常,因为它只是一个结果。 将它放入派生表
SELECT * FROM (
SELECT custid AAA, companyname + ''
FROM Sales.Customers
WHERE country = 'USA'
) AS AAA
SQL Server返回:没有为“AAA”的第2列指定列名。
这也解释了为什么在派生表语法中,必须为表(AS AAA)分配别名,因为表必须具有名称。
谢谢大家。