2015-10-16 42 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