2012-09-25 48 views
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 
+2

我不知道,但我會看看是使用保留字數作爲別名。再次,我不使用sql服務器,所以我不知道這是否是問題。但無論如何這是不好的做法。 – ajon

+0

所以人們不必像我那樣分析他們的答案,你可以在你的問題中包含SQL Server版本*嗎? –

回答

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兼容的語法,而不是專有的巫術。

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 - 我希望你真正的表,列和查詢不濫用保留字是這樣的。

+0

我的天啊!爲什麼sql-server中的SQL比起pg/mysql來說太複雜了...... – marioosh

+1

@marioosh因爲SQL Server按照標準做了這個正確的方法,而不是提出這個LIMIT廢話。您可以從SQL Server 2012開始使用OFFSET/FETCH。我不知道您是否可以使用它,因爲您沒有指定版本。 –

+0

另外,如果你不是基於聚合進行分頁的話,它會更簡單一些。如果查詢太難,您可以考慮索引視圖。 –

-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功能

+2

'id by order by'會因爲'id'沒有分組而導致錯誤 – 2012-09-25 22:14:52

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