Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如果可以按1排序,为什么我不能按1分组?_Sql - Fatal编程技术网

Sql 如果可以按1排序,为什么我不能按1分组?

Sql 如果可以按1排序,为什么我不能按1分组?,sql,Sql,为什么列序号适用于ORDER BY而不适用于GROUP BY?也就是说,有谁能告诉我为什么这个问题 SELECT OrgUnitID, COUNT(*) FROM Employee AS e GROUP BY OrgUnitID 不能写成 SELECT OrgUnitID, COUNT(*) FROM Employee AS e GROUP BY 1 当编写这样的查询是完全合法的时候 SELECT OrgUnitID FROM Employee AS e ORDER BY 1 ? 我真的很

为什么列序号适用于ORDER BY而不适用于GROUP BY?也就是说,有谁能告诉我为什么这个问题

SELECT OrgUnitID, COUNT(*) FROM Employee AS e GROUP BY OrgUnitID
不能写成

SELECT OrgUnitID, COUNT(*) FROM Employee AS e GROUP BY 1
当编写这样的查询是完全合法的时候

SELECT OrgUnitID FROM Employee AS e ORDER BY 1
?

我真的很想知道关系演算是否有什么微妙的地方,或者会阻止分组正常工作的东西

问题是,我的例子很简单。通常,我想要分组的列实际上是一个计算,必须在分组中重复完全相同的计算是一个恼人的问题,并且b在维护期间更可能出错。下面是一个简单的例子:

SELECT DATEPART(YEAR,LastSeenOn), COUNT(*)
    FROM Employee AS e
    GROUP BY DATEPART(YEAR,LastSeenOn)
我认为SQL的规范化规则(只在数据库中表示一次数据)也应该扩展到代码。我只想在“选择列”列表中对该计算表达式进行一次修改,并能够在“分组依据”中按序号引用它

澄清:我正在专门研究SQL Server 2008,但我想知道一个总体答案。

使用别名:

SELECT DATEPART(YEAR,LastSeenOn) as 'seen_year', COUNT(*) as 'count'
    FROM Employee AS e
    GROUP BY 'seen_year'
**编辑**

如果您不允许按别名分组,这里有一个解决方案/解决方法:

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

其中一个原因是,ORDERBY是SQL查询中运行的最后一项,下面是操作顺序

FROM子句 WHERE子句 分组依据子句 有从句 SELECT子句 按条款订货 因此,一旦您拥有SELECT子句中的列,就可以使用顺序定位

编辑,根据评论添加此内容 以此为例,

create table test (a int, b int)
insert test values(1,2)
go
下面的查询将毫无问题地解析,它不会运行

select a as b, b as a
     from test
    order by 6
这里是错误

味精108,16级,状态1,第3行 按位置编号6排序超出了选择列表中项目数的范围

这也很好

select a as b, b as a
     from test
    group by 1
但它却因为这个错误而爆炸

味精164,第15级,状态1,第3行
每个GROUP BY表达式必须至少包含一个非外部引用的列。

我不确定标准是否指定了它是否有效,但我相信它取决于实现。我刚刚用一个SQL引擎尝试了您的第一个示例,它运行得很好。

SQL中有很多基本的不一致,使用标量就是其中之一。例如,任何人都可能期望


作为一个类似的查询,这两个查询之间的差异可以被无限小地缩小,毕竟这是不可能的

无法在SQL Server中工作。。。。每个GROUP BY表达式必须至少包含一个非外部引用的列。您的编辑肯定会起作用。由于我使用的是SQL Server 2008,我可能会在CTE中编写它以使其更干净。毫无疑问,有办法解决这个问题。我真的希望通过查看限制是否有真正的原因来扩展我对SQL的理解。您使用的是什么SQL?这是标准的查询语言,毕竟不是那么标准……按n编码的顺序比按列编码的顺序更难维护,因为有人会进来,在查询中添加一列,并在不知不觉中更改排序。我认为SELECT*和ORDER BY n对于快速开发工作是可接受的,但对于生产来说是完全不可接受的queries@KM-这当然是一个正确的观点,我的一位同事说了同样的话,但我认为这是一个平衡邪恶的问题。至少在某些情况下,必须重述的表达的复杂性似乎使其成为更大的罪恶。另外,我还想知道为什么。@Yanick:这是结构化查询语言,不是标准查询语言。你说的不太标准是对的……但是你所说的与查询的实际执行有关。据我所知,在实际执行任何操作之前,解释器可以在解析查询时解析序号。我认为您的示例不正确。代码在语法上是正确的,所以从技术上讲,它确实成功地通过了解析阶段。我不知道如何检查这一点,但我敢打赌,在您的两个错误示例中,查询从来没有实际执行过,没有检查任何数据或索引页。查询优化器可以很容易地看到ORDER示例没有6列。由于给定SELECT子句,查询是非法的,所以GROUP示例失败的时间甚至比这还要早。

    select * from countries
    order by 1

    select * from countries
    order by 1.00001