我正在为我的网格提取数据
SELECT
Orders.CustomerID,
Orders.OrderTime,
OrderItems.ProductID,
OrderItems.Quantity
FROM
dbo.Orders INNER JOIN dbo.OrderItems
ON Orders.ID = OrderItems.OrderID
我还需要分页的总数。
有两种选择。
1-做另一次获取
SELECT count(*) FROM dbo.Orders
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
我应该走哪条路?
答案 0 :(得分:2)
在您提出的两种方法中,第一种(单独查询)更好。第二种方法意味着计数将出现在返回的每一行中,这有点不必要。此外,如果查询返回20行,select count(*)
将执行20次(如果我没记错的话,猜测这可能取决于你正在使用的数据库引擎)。
此外,根据您正在设想的流量以及表格可能获得的大小,您可以通过在某处缓存select count(*)
的结果,然后在插入/删除时刷新它来改进此桌子。
答案 1 :(得分: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这样的单独查询。
答案 2 :(得分: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
答案 3 :(得分:1)
正如@Mailslut建议的那样,你应该使用两个查询。但是,您应该添加一个
获取数据的查询的WHERE
子句,因此您只获取实际需要显示的数据(除非您正在缓存它)。
如果一次有多个线程访问数据库,您还需要以某种方式确保计数与数据库保持同步。
答案 4 :(得分:1)
我会考虑不同的东西,因为你要做的不是很简单,而是非常必要。您是否考虑过使用SQL Server row_number函数?通过这种方式,您可以通过查看返回的max 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