我必须将一些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
答案 0 :(得分: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;
根据mohan的回答,这可以缩短一点。
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兼容语法而不是专有的巫术语。
SELECT c = COUNT(id), d = [date]
FROM dbo.table GROUP BY [date]
ORDER BY COUNT(id)
OFFSET 25 ROWS FETCH NEXT 10 ROWS ONLY;
我blogged about this functionality in 2010(那里也有很多好的评论)并且应该投入一些时间做一些严肃的性能测试。
我同意@ajon - 我希望你的真实表格,专栏和查询不会滥用这样的保留字。
答案 1 :(得分: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
答案 2 :(得分:-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有一个新的Paging功能