2010-07-01 99 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所说。