为什么我不能分组1当ORDER BY 1可以?

Chr*_*eld 13 sql

为什么列标准合法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,但我想知道总体答案.

SQL*_*ace 8

其中一个原因是因为ORDER BY是SQL Query中运行的最后一件事,这是操作的顺序

  1. FROM子句
  2. WHERE子句
  3. GROUP BY子句
  4. HAVING子句
  5. SELECT子句
  6. ORDER BY子句

因此,一旦获得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表达式必须包含至少一个不是外部引用的列.


Yan*_*hon 1

使用别名:

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)

  • 在 SQL Server 中不起作用...每个 GROUP BY 表达式必须至少包含一列不是外部引用。 (2认同)