为什么列标准合法ORDER BY
但不适用GROUP BY
?也就是说,任何人都可以告诉我为什么这个查询
SELECT OrgUnitID, COUNT(*) FROM Employee AS e GROUP BY OrgUnitID
Run Code Online (Sandbox Code Playgroud)
不能写成
SELECT OrgUnitID, COUNT(*) FROM Employee AS e GROUP BY 1
Run Code Online (Sandbox Code Playgroud)
当写一个像这样的查询是完全合法的
SELECT OrgUnitID FROM Employee AS e ORDER BY 1
Run Code Online (Sandbox Code Playgroud)
?
我真的很想知道关系微积分是否存在一些微妙的东西,这会阻止分组正常工作.
问题是,我的例子非常简单.通常我想要分组的列实际上是一个计算,并且必须在GROUP BY中重复完全相同的计算是(a)烦人和(b)更有可能在维护期间产生错误.这是一个简单的例子:
SELECT DATEPART(YEAR,LastSeenOn), COUNT(*)
FROM Employee AS e
GROUP BY DATEPART(YEAR,LastSeenOn)
Run Code Online (Sandbox Code Playgroud)
我认为,规范化的SQL的规则,只表示数据在数据库中一次应该扩展到代码.我想只对这个计算表达式做一次(在SELECT
列列表中),并且能够通过序数引用它GROUP BY
.
澄清:我专门研究SQL Server 2008,但我想知道总体答案.
其中一个原因是因为ORDER BY是SQL Query中运行的最后一件事,这是操作的顺序
因此,一旦获得SELECT子句中的列,就可以使用序数定位
编辑,基于评论添加这个以此为例
create table test (a int, b int)
insert test values(1,2)
go
Run Code Online (Sandbox Code Playgroud)
下面的查询将解析没有问题,它将无法运行
select a as b, b as a
from test
order by 6
Run Code Online (Sandbox Code Playgroud)
这是错误
消息108,级别16,状态1,行3
ORDER BY位置编号6超出了选择列表中项目数的范围.
这也解析得很好
select a as b, b as a
from test
group by 1
Run Code Online (Sandbox Code Playgroud)
但它会因此错误而爆炸
消息164,级别15,状态1,行3
每个GROUP BY表达式必须包含至少一个不是外部引用的列.
使用别名:
SELECT DATEPART(YEAR,LastSeenOn) as 'seen_year', COUNT(*) as 'count'
FROM Employee AS e
GROUP BY 'seen_year'
Run Code Online (Sandbox Code Playgroud)
**编辑**
如果GROUP BY alias
您不允许,这里有一个解决方案/解决方法:
SELECT seen_year
, COUNT(*) AS Total
FROM (
SELECT DATEPART(YEAR,LastSeenOn) as seen_year, *
FROM Employee AS e
) AS inline_view
GROUP
BY seen_year
Run Code Online (Sandbox Code Playgroud)