53

我的代码如下所示:

select col1,count(col2) as col7
from --some join operation
group by col1
having col7 >= 3 -- replace col7 by count(col2) to make the code work

我的代码导致错误“列名 'col7' 无效”。为什么会这样?SQL 不允许我在最后一行使用 col7 似乎不合逻辑。

我正在使用 SQL Server Express 2008

4

8 回答 8

57

HAVING子句在 - 之前进行评估,SELECT因此服务器还不知道该别名。

  1. 首先,FROM形成子句中所有表的乘积。

  2. 然后评估该WHERE子句以消除不满足 search_condition 的行。

  3. GROUP BY接下来,使用子句中的列对行进行分组。

  4. 然后,消除不满足子句中的search_condition组。HAVING

  5. 接下来,SELECT评估语句目标列表中的表达式。

  6. 如果DISTINCTselect 子句中存在关键字 in,则现在消除重复行。

  7. UNION评估每个子选择之后进行。

  8. 最后,根据ORDER BY子句中指定的列对结果行进行排序。

  9. TOP子句被执行。

希望这能回答你的问题。此外,它解释了为什么别名在ORDER BY子句中起作用。

于 2016-08-16T15:21:02.347 回答
34

在 MS SQL 中,唯一可以引用别名的地方(我知道)是在 ORDER BY 子句中。在查询的其他部分引用别名的能力是许多其他数据库平台所具有的功能,老实说,微软认为它没有足够有用的功能来添加它,这让我很恼火。

于 2012-12-27T04:56:29.153 回答
7

尝试使用这个,因为选择列表包含您可以在 having 子句中使用的相同表达式:

SELECT COL1,COUNT(COL2) AS COL7
FROM --SOME JOIN OPERATION
GROUP BY COL1
HAVING COUNT(COL2) >= 3 
于 2012-12-27T04:43:27.203 回答
6

您应该选择两次以使用 count() 列

select * from (select col1,count(col2) as col7
from --some join operation
group by col1) as temp
where temp.col7 >= 3
于 2012-12-27T02:29:45.327 回答
1

你可以使用这个代码:

IF OBJECT_ID('tempdb..#temp') is not null DROP TABLE #temp

-- Create tempurary table
CREATE TABLE #temp (Id BIGINT IDENTITY(1,1), col1 BIGINT, countOfcol2 BIGIN)

--insert from the table 2 #temp
INSERT INTO #temp (col1,countOfcol2) 

select col1,count(col2) as col7
from --some join operation

select col1,countOfcol2 from #temp
group by col1
having countOfcol2 >= 3 -- replace col7 by count(col2) to make the code work
于 2012-12-27T08:07:16.347 回答
1

您可以使用嵌套查询来解决此问题。

当我想提高性能时,我也遇到了这个问题。我需要count()基于表中 JSON 字段中的某些字段运行 a,显然我们只想解析 JSON 一次,而不必在whereorhave子句中包含单独的计数(尤其是像我这样的昂贵的子句)。

如果col1是一个唯一的 id,那么计算效率最高的方法可能是将计数嵌套在一个单独的select

select col1, innerquery.col7
from whatevertable
inner join (select col1, count(col2) as col7 
            from whatevertable 
            group by col1) as innerquery 
            on innerquery.col1 = whatevertable.col1
where innerquery.col7 >= 3;

这样计数只运行一次,创建一种临时查找表以供其余查询参考。

同样,这仅col1在每条记录都是唯一的情况下才有效,这通常不会问太多,因为大多数表都有某种 id 主键。

于 2018-04-03T20:10:08.997 回答
0

select col1,count(col2) as col7 from --some join operation group by col1 with count(col2) >= 3;

老实说,我对为什么 SQL Server 不处理列别名感到恼火。我将此用作解决方法。它仍然将列名打印为您的别名,但使用原始聚合函数进行处理。

于 2016-07-23T19:29:53.000 回答
0

在 SQL 中,子句的执行流程是 From --> where --> group by --> having --> select --> order by --> distinct --> top。

由于在 select 子句中声明了别名,因此它不适用于在 select 之前执行的子句(它适用于仅在 select 之后执行的子句)但是还有另一种使用别名的方法,通过使用嵌套 select 例如:select * from (选择姓名、薪水、薪水+1000 作为员工加薪)作为员工,其中加薪 > 10000;

于 2020-06-29T10:20:58.387 回答