2015-10-16 141 views
1

我想分頁SQL Server行。我在網上找到了一些教程,但我無法掌握每一個細節,這導致我在將their examples改編爲我現有的查詢時失敗了。如何爲使用GROUP BY和聚合時分頁SQL Server行

本教程的說明:

USE AdventureWorks2008R2 
GO 
SELECT 
    m.RowNr, 
    m.SalesOrderID, 
    m.SalesOrderDetailID, 
    m.OrderQty, 
    m.ProductID, 
    m.UnitPrice, 
    m.LineTotal, 
    m.rowguid, 
    m.ModifiedDate 
FROM 
    (
    SELECT 
     ROW_NUMBER() OVER(ORDER BY SalesOrderDetailID DESC) AS RowNr, 
     SalesOrderID, 
     SalesOrderDetailID, 
     OrderQty, 
     ProductID, 
     UnitPrice, 
     LineTotal, 
     rowguid, 
     ModifiedDate 
    FROM Sales.SalesOrderDetail AS tbl 
)m 
WHERE RowNr BETWEEN 1 AND 10; 

我現有的(非分頁)查詢:

SELECT DISTINCT 
    MAX(i.ID) AS ID, 
    i.ItemLookupCode, 
    MAX(CAST(i.Notes AS varchar(max))) AS Notes, 
    MAX(CONVERT(varchar(30), i.Price, 1)) AS Price, 
    MAX(i.PictureName) AS PictureName 

FROM Item AS i 

LEFT JOIN nitroasl_pamtable AS n 
    ON i.ID = n.ItemID 

WHERE (i.ID LIKE '%hdmi%' OR i.ItemLookupCode LIKE '%hdmi%' OR i.Notes LIKE '%hdmi%' OR i.Description LIKE '%hdmi%' OR i.ExtendedDescription LIKE '%hdmi%' OR n.ManufacturerPartNumber LIKE '%hdmi%' OR n.PAM_Keywords LIKE '%hdmi%') 
AND (i.WebItem = 0 AND i.Price > 0) 

GROUP BY i.ItemLookupCode 

ORDER BY i.ItemLookupCode ASC; 

我嘗試

/* Return Page */ 
SELECT 
    i.RowID, 
    MAX(i.ID) AS ID, 
    i.ItemLookupCode, 
    MAX(CAST(i.Notes AS varchar(max))) AS Notes, 
    MAX(CONVERT(varchar(30), i.Price, 1)) AS Price, 
    MAX(i.PictureName) AS PictureName 
FROM (
    SELECT 

    /* The following row is the line that is being blamed by the error */ 
    ROW_NUMBER() OVER(ORDER BY ItemLookupCode) AS RowID, 

    MAX(ID) AS ID, 
    ItemLookupCode, 
    MAX(CAST(Notes AS varchar(max))) AS Notes, 
    MAX(CONVERT(varchar(30), Price, 1)) AS Price, 
    MAX(PictureName) AS PictureName 
    FROM Item AS tbl 
) AS i 

WHERE RowID BETWEEN 1 AND 15; 

上面的查詢將返回以下錯誤:

Msg 8120, Level 16, State 1, Line 12 Column 'Item.ItemLookupCode' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

誰能誰是與SQL Server有更多的瞭解(2008 R2)幫我在這裏填寫的空白?

回答

2

您需要對分組結果應用rownumber。

WITH cteresults AS 
(
    SELECT DISTINCT Max(i.id) AS ID, 
     i.itemlookupcode, 
     Max(Cast(i.notes AS VARCHAR(max))) AS Notes, 
     Max(CONVERT(VARCHAR(30), i.price, 1)) AS Price, 
     Max(i.picturename) AS PictureName 
    FROM item AS i 
     LEFT JOIN nitroasl_pamtable AS n ON i.id = n.itemid 
    WHERE (i.id LIKE '%hdmi%' 
      OR i.itemlookupcode LIKE '%hdmi%' 
      OR i.notes LIKE '%hdmi%' 
      OR i.description LIKE '%hdmi%' 
      OR i.extendeddescription LIKE '%hdmi%' 
      OR n.manufacturerpartnumber LIKE '%hdmi%' 
      OR n.pam_keywords LIKE '%hdmi%') 
     AND (i.webitem = 0 AND i.price > 0) 
    GROUP BY i.itemlookupcode 
) 
,ctepagination AS 
(
    SELECT *, Row_number() OVER(ORDER BY itemlookupcode) AS RowID 
    FROM cteresults 
) 

SELECT * 
FROM ctepagination 
WHERE rowid BETWEEN 1 AND 15 

這應該沒有CTE。但是,不知道它是否可以解決您在評論中提到的問題。

SELECT * FROM 
(
    SELECT *, Row_number() OVER(ORDER BY itemlookupcode) AS RowID from 
    (
     SELECT DISTINCT Max(i.id) AS ID, 
      i.itemlookupcode, 
      Max(Cast(i.notes AS VARCHAR(max))) AS Notes, 
      Max(CONVERT(VARCHAR(30), i.price, 1)) AS Price, 
      Max(i.picturename) AS PictureName 
     FROM item AS i 
      LEFT JOIN nitroasl_pamtable AS n ON i.id = n.itemid 
     WHERE (i.id LIKE '%hdmi%' 
       OR i.itemlookupcode LIKE '%hdmi%' 
       OR i.notes LIKE '%hdmi%' 
       OR i.description LIKE '%hdmi%' 
       OR i.extendeddescription LIKE '%hdmi%' 
       OR n.manufacturerpartnumber LIKE '%hdmi%' 
       OR n.pam_keywords LIKE '%hdmi%') 
      AND (i.webitem = 0 AND i.price > 0) 
     GROUP BY i.itemlookupcode 
    ) t1 
) t2 
WHERE rowid BETWEEN 1 AND 15 
+0

謝謝你。我不會想到這一點。以這種方式查看格式化查詢也有助於我瞭解究竟發生了什麼。謝謝! – derekmx271

+0

因此,請注意,PHP的sqlsrv驅動程序不喜歡查詢。它成功了,但是沒有返回行嗎?......有沒有可能用不同的方法來格式化這個查詢,這個驅動程序可能會更好一點? – derekmx271

+0

夥計,這個作品真棒!非常非常感謝你! – derekmx271