哎呀呀呀呀!我已经苦恼了很久!我可以使用MySQL轻松做到,但不是用SQL Server :(
这里是应该全部联接在一起的简化表格。
通过使用内部联接语法来组合它们所有,我必须编写一个查询以备将来分页使用(PHP)。 假设我需要在2012-10-01至2012-10-30之间拍摄的所有ID、名称和日期信息......每页20个人。
在这里实现目标最简单的查询是什么?(我尝试过NOT IN.. 但因为我不习惯“NOT IN”的东西,它有点小瑕疵...)
您可以忽略性能速度。
谢谢!
哎呀呀呀呀!我已经苦恼了很久!我可以使用MySQL轻松做到,但不是用SQL Server :(
这里是应该全部联接在一起的简化表格。
通过使用内部联接语法来组合它们所有,我必须编写一个查询以备将来分页使用(PHP)。 假设我需要在2012-10-01至2012-10-30之间拍摄的所有ID、名称和日期信息......每页20个人。
在这里实现目标最简单的查询是什么?(我尝试过NOT IN.. 但因为我不习惯“NOT IN”的东西,它有点小瑕疵...)
您可以忽略性能速度。
谢谢!
SELECT ID, Name, Photo, CreatedDate, rowNum, (rowNum / 20) + 1 as pageNum
FROM (
SELECT a.ID, a.Name, b.Photo, c.Created_Date
, Row_Number() OVER (ORDER BY c.Created_Date ASC) as rowNum
FROM a
JOIN b ON a.ID = b.ID
JOIN c ON c.photo = b.photo
WHERE c.Created_Date BETWEEN '2012-01-1' AND '2012-10-30'
) x
WHERE (rowNum / 20) + 1 = 1
SELECT a.ID, a.Name, b.Photo, c.Created_Date
, identity(int,1,1) as rowNum
INTO t
FROM a
JOIN b ON a.ID = b.ID
JOIN c ON c.photo = b.photo
WHERE c.Created_Date BETWEEN '2012-01-1' AND '2012-10-30'
ORDER BY c.Created_Date ASC
GO
ALTER TABLE t ADD pageNum AS rowNum / 20
GO
SELECT ID, Name, Photo, Created_Date, rowNum
FROM t
WHERE pageNum = 1
以下是我很久以前的做法...
SELECT * FROM (
SELECT TOP y * FROM (
SELECT TOP x * FROM sometable
ORDER BY somefield ASC
)
ORDER BY somefield DESC)
ORDER BY somefield
微软在SQL Server 2012及以上版本中添加了原生分页功能,使用"OFFSET" 和 "FETCH"。您可以按以下方式使用此功能:
-- Skip the first 500 rows and return the next 100
SELECT *
FROM TableName
ORDER BY [ID]
OFFSET 500 ROWS
FETCH NEXT 100 ROWS ONLY;
OFFSET __
和 FETCH NEXT __
子句,您可以指定常量值(如上所示),也可以指定变量、表达式或常量标量子查询。使用 Sql Server 2008 + AdventureWorks 数据库尝试此操作。
DECLARE @PageIndex INT, @RowsPerPage INT
DECLARE @StartRow INT, @EndRow INT;
SET @PageIndex = 1;
SET @RowsPerPage = 500;
SET @StartRow = ((@PageIndex - 1) * @RowsPerPage) + 1;
SET @EndRow = @StartRow + @RowsPerPage - 1;
--append#1
WITH PAGE_ROWS
AS
(
SELECT ROW_NUMBER() OVER(ORDER BY OrderDate DESC, SalesOrderNumber ASC) AS ROW_NO
, COUNT(*) OVER() AS TOTAL_ROWS
, *
FROM(
--working query
SELECT S.SalesOrderID
, S.SalesOrderNumber
, S.OrderDate
, S.DueDate
, S.ShipDate
, S.Status
, S.PurchaseOrderNumber
, C.AccountNumber
, P.FirstName, P.MiddleName, P.LastName
FROM [Sales].[SalesOrderHeader] AS S
LEFT OUTER JOIN [Sales].[Customer] AS C ON C.CustomerID=S.CustomerID
LEFT OUTER JOIN [Person].[Person] AS P ON P.BusinessEntityID=C.PersonID
--append#2
) AS Src)
SELECT CEILING(TOTAL_ROWS/ CAST(@RowsPerPage AS DECIMAL(20,2))) AS TOTAL_PAGES
,*
FROM PAGE_ROWS
WHERE ROW_NO BETWEEN @StartRow AND @EndRow
ORDER BY OrderDate DESC, SalesOrderNumber ASC
我喜欢Taha Siddiqui的答案,但它需要修改传入的查询,并且对于我必须使用SQL UNION语句的情况(由前同事做出的一些非常糟糕的设计决策),它并不起作用。
通用的SQL Server查询如下:
SELECT * FROM (
select ROW_NUMBER() OVER (order by ID) as row_num, * FROM (
<<Put Your Query Here>>
) AS tempTable1
) AS tempTable2 WHERE row_num >= ((pageNum -1) * pageSize) AND row_num < ((pageNum -1) * pageSize) + pageSize;
public static String buildPagingQuery(String sqlStr, String sortExpression, int pageNum, int pageSize) {
if (StringUtils.isBlank(sortExpression)) { //NOTE: uses org.apache.commons.lang.StringUtils
sortExpression = " (select 0)";
}
int startIndex = ((pageNum - 1) * pageSize) + 1;
int endIndex = startIndex + pageSize;
StringBuilder sb = new StringBuilder();
sb.append("SELECT * FROM (");
sb.append("SELECT ROW_NUMBER() OVER (ORDER BY ");
sb.append(sortExpression);
sb.append(") as row_num, * FROM (");
sb.append(sqlStr);
sb.append(") as tempTable1 ");
sb.append(") AS tempTable2 ");
sb.append("WHERE row_num >= ").append(startIndex);
sb.append(" AND row_num < ").append(endIndex);
return sb.toString();
}
我尚未检查大表的性能。
ALTER Proc [dbo].[Sp_PagingonTable]
@SearchText varchar(255) = null,
@ChannelName varchar(255)= null,
@ChannelCategory varchar(255)= null,
@ChannelType varchar(255)= null,
@PageNo int,
@PageSize int,
@TotalPages int output
As
DECLARE @VariableTable TABLE
(
Rownumber INT,
ReferralHierarchyKey BIGINT,
ReferralID VARCHAR(255),
ChannelDetail VARCHAR(255),
ChannelName VARCHAR(255),
ChannelCategory VARCHAR(255),
ChannelType VARCHAR(255)
)
/*---Inserting Data into variable Table-------------*/
INSERT INTO @VariableTable
SELECT
ROW_NUMBER() OVER(ORDER BY [ColumnID) as Rownumber,*
FROM [dbo].[TableName]
WHERE (@SearchText IS NULL OR ChannelDetail LIKE '%' + @SearchText + '%') And (@ChannelName IS NULL OR ChannelName = @ChannelName )
/*--Applying Paging on filter Table--*/
SELECT
ReferralID
,ChannelDetail
,ChannelName
,ChannelCategory
,ChannelType
FROM
@VariableTable
WHERE Rownumber between (((@PageNo -1) *@PageSize)+1) and @PageNo * @PageSize
/*--Getting Total Pages After filter Table---*/
SELECT @TotalPages = (Count(*) + @PageSize - 1)/@PageSize FROM @VariableTable
SELECT @TotalPages
DECLARE @PageSize INT=1 ,@PageNumber INT=2
DECLARE @Offset int =(@PageSize * (@PageNumber - 1))+1
;WITH Results_CTE AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY FieldName) AS RowNum
FROM TABLENAME
)
SELECT *
FROM Results_CTE
WHERE RowNum>=@Offset AND RowNum < @Offset + @PageSize
END
https://amonghorizon.blogspot.com/2020/07/sql-server-query-for-pagination-control.html
internal class PagingHelper
{
public static String ParseQueryForPagingAndSorting(String strSQL, string SortExpression, int StartIndex, int EndIndex)
{
if (String.IsNullOrEmpty(SortExpression))
SortExpression = " (select 0)";
StringBuilder sb = new StringBuilder();
sb.Append("select * from (");
sb.Append(" select ROW_NUMBER() OVER (ORDER BY " + SortExpression + ") AS row_num,");
int index = strSQL.ToLower().IndexOf('t', 0);
sb.Append(strSQL.Substring(index + 2));
sb.Append(")");
sb.Append(" AS TempTable");
sb.Append(" where row_num>=" + StartIndex.ToString() + " AND row_num<=" + EndIndex.ToString());
return sb.ToString();
}
public static String ParseQueryForCount(String strSQL)
{
StringBuilder sb = new StringBuilder();
sb.Append("select count(*) from");
sb.Append("(");
sb.Append(strSQL);
sb.Append(")");
sb.Append(" AS TempTable");
return sb.ToString();
}
}
我发现了另一种在Sql server 2012中实现此操作的方法
http://raresql.com/2012/07/01/sql-paging-in-sql-server-2012-using-order-by-offset-and-fetch-next/