2010-07-01 67 views
0

我獲取的數據爲我網這樣數據庫分頁設計

SELECT 
    Orders.CustomerID, 
    Orders.OrderTime, 
    OrderItems.ProductID, 
    OrderItems.Quantity 
    FROM 
    dbo.Orders INNER JOIN dbo.OrderItems 
     ON Orders.ID = OrderItems.OrderID 

我還需要分頁的總數。

有兩種選擇。

1-做的另一種獲取

​​

2-把count語句查詢

SELECT 
    Orders.CustomerID, 
    Orders.OrderTime, 
    OrderItems.ProductID, 
    OrderItems.Quantity, 
    (SELECT count(*) FROM dbo.Orders) as Count 
    FROM 
    dbo.Orders INNER JOIN dbo.OrderItems 
     ON Orders.ID = OrderItems.OrderID 

我應該走哪條路?

回答

2

您提出的兩種方法中,第一種(單獨查詢)更好。第二種方法意味着計數將出現在返回的每一行中,這是不必要的。此外,如果查詢返回20行,select count(*)將執行20次(如果我記得沒錯,猜測這可能取決於您使用的是哪個數據庫引擎)。

此外,根據您設想的流量和表可能有多大,您可以通過在某處緩存select count(*)的結果,然後在插入/刪除表時刷新它,從而改善此情況。

+0

另外,您應該使用「LIMIT」來獲取您需要的記錄。這在進行分頁時會被重新編輯。您首先使用count進行查詢,然後根據「頁面」和「計數」(確定最高可能頁面)和頁面大小進行限制查詢。 – Alxandr 2010-07-01 09:59:03

1

如果你是使用oracle你可以使用COUNT(*) OVER () CNT。這一次是更有效的 ,因爲它需要一個表掃描

SELECT 
    Orders.CustomerID, 
    Orders.OrderTime, 
    OrderItems.ProductID, 
    OrderItems.Quantity, 
    COUNT(*) OVER () CNT as Count 
    FROM 
    dbo.Orders INNER JOIN dbo.OrderItems 
     ON Orders.ID = OrderItems.OrderID 
1

由於@Mailslut建議,你應該使用兩個查詢。但是,您應該向獲取數據的查詢添加一個 WHERE子句,因此您只能獲取實際需要顯示的數據(除非您正在緩存該數據)。

如果多個線程一次訪問數據庫,您還需要以某種方式確保計數與數據庫保持同步。

1

我會考慮一些不同的事情,因爲你試圖做的不是很簡單,但是非常必要。你有沒有考慮過使用SQL Server row_number函數?這樣你就可以通過查看返回的最大row_number來知道有多少條記錄,但也可以按照你想要的順序。

SELECT 
    Orders.CustomerID, 
    Orders.OrderTime, 
    OrderItems.ProductID, 
    OrderItems.Quantity, 
    ROW_NUMBER() OVER(ORDER BY Orders.CustomerId) rn 
    FROM 
    dbo.Orders INNER JOIN dbo.OrderItems 
     ON Orders.ID = OrderItems.OrderID 
2

如果這適用於SQL Server 2005或更高版本,獲得分頁的最佳方法之一是使用Common Table Expression

CREATE PROC MyPaginatedDataProc 
@pageNumber INT 
AS 

WITH OrdersCTE (CustomerID, OrderTime, ProductID, Quantity, RowNumber) 
AS 
(
    SELECT 
     Orders.CustomerID, 
     Orders.OrderTime, 
     OrderItems.ProductID, 
     OrderItems.Quantity, 
     ROW_NUMBER() OVER (ORDER BY OrderItems.OrderID) AS RowNumber 
    FROM 
     dbo.Orders INNER JOIN dbo.OrderItems ON Orders.ID = OrderItems.OrderID 
) 

SELECT 
    CustomerID, 
    OrderTime, 
    ProductId, 
    Quantity 
FROM 
    OrdersCTE 
WHERE 
    RowNumber BETWEEN (@pageNumber * 10) AND (((@pageNumber + 1) * 10) -1) 

否則爲獲取總行數,我會使用一個單獨的查詢,如Mailslut所說。