1

我必须将一些 SQL 从 PostgreSQL 迁移到 SQL Server (2005+)。在 PostgreSQL 上我有:

select count(id) as count, date
from table 
group by date 
order by count 
limit 10 offset 25

现在我需要相同的 SQL,但用于 SQL Server。我像下面那样做了,但得到错误:Invalid column name 'count'.如何解决?

select * from (
   select row_number() over (order by count) as row, count(id) as count, date 
   from table 
   group by date
) a where a.row >= 25 and a.row < 35
4

3 回答 3

5

您不能在同一范围内按名称引用别名,但结尾 ORDER BY除外(它是同一范围内的窗口函数内部的无效引用)。

要获得完全相同的结果,可能需要将其扩展到(为了清晰起见,嵌套范围):

SELECT c, d FROM 
(
  SELECT c, d, ROW_NUMBER() OVER (ORDER BY c) AS row FROM 
  (
    SELECT d = [date], c = COUNT(id) FROM dbo.table GROUP BY [date]
  ) AS x
) AS y WHERE row >= 25 AND row < 35;

根据莫汉的回答,这可以缩短一点。

SELECT c, d FROM 
(
  SELECT COUNT(id), [date], ROW_NUMBER() OVER (ORDER BY COUNT(id))
   FROM dbo.table GROUP BY [date]
) AS y(c, d, row)
WHERE row >= 25 AND row < 35;

在 SQL Server 2012 中,使用OFFSET / FETCH更容易- 更接近您习惯的语法,但实际上使用的是与 ANSI 兼容的语法,而不是专有的 voodoo。

SELECT c = COUNT(id), d = [date]
FROM dbo.table GROUP BY [date]
ORDER BY COUNT(id)
OFFSET 25 ROWS FETCH NEXT 10 ROWS ONLY;

在 2010 年写了一篇关于这个功能的博客(那里也有很多好的评论),可能应该花一些时间做一些严肃的性能测试。

我同意@ajon - 我希望你的真实表、列和查询不会像这样滥用保留字。

于 2012-09-25T21:32:39.480 回答
3

有用

DECLARE @startrow int=0,@endrow int=0

;with CTE AS (

select row_number() over ( order by count(id)) as row,count(id) AS count, date
from table
group by date 
)
SELECT * FROM CTE 
WHERE  row between @startrow and @endrow
于 2012-09-25T22:07:37.987 回答
-3

我认为这会做到

select * from (
   select row_number() over (order by id) as row, count(id) as count, date 
   from table 
   group by date
) a where a.row >= 25 and a.row < 35

另外,我不知道您使用的是什么版本的 SQL Server,但 SQL Server 2012 有一个新的分页功能

于 2012-09-25T21:32:44.510 回答