2014-09-25 91 views
0

我在分页查询时出现问题。我试过here的例子,但它给出了一些“光标”错误。SQL Server 2008分页复杂查询

SELECT Countries.CountryID, Countries.Name as CountryName, Customers.FName, Customers.LName, Customers.EMail, LTRIM(Organizations.OrgName) AS OrgName, Organizations.URL, Addresses.City, Addresses.State, Countries.Name,Addresses.Zip 
FROM (((Customers INNER JOIN CustomerMembershipXRef ON Customers.CustomerID = CustomerMembershipXRef.CustomerID) INNER JOIN Organizations ON Customers.OrgID = Organizations.OrgID) INNER JOIN (Countries INNER JOIN Addresses ON Countries.CountryID = Addresses.CountryID) ON Customers.CustomerID = Addresses.EntityID) INNER JOIN Memberships ON (Organizations.OrgID = Memberships.OrgID) AND (CustomerMembershipXRef.MembershipID = Memberships.MembershipID) 
WHERE (Memberships.ExpireDate > GETDATE()) AND (Addresses.EntityTypeID=200) AND (Customers.RecordStatus='A') AND (Memberships.RecordStatus='A') AND(Organizations.OrgTypeID=46 OR Organizations.OrgTypeID=55) AND (Addresses.State = 'MI ') 
ORDER BY Customers.LName ASC, Organizations.OrgName, Addresses.City, Addresses.State 

我需要使其显示50每页......在MySQL这将是简单LIMIT 100,50 3页,但MS SQL 2008不那样做......请帮助我的为此查询分页的最佳方式。

SELECT CountryID, CountryName, FName, LName, EMail, OrgName, OrgURL, City, State, CountryName,Zip 
FROM (SELECT Countries.CountryID as CountryID, Countries.Name as CountryName, Customers.FName as FName, Customers.LName as LName, Customers.EMail as EMail, LTRIM(Organizations.OrgName) AS OrgName, Organizations.URL as OrgURL, Addresses.City as City, Addresses.State as State, Countries.Name as CountryName, Addresses.Zip as Zip, ROW_NUMBER() OVER (ORDER BY Customers.LName ASC, Organizations.OrgName, Addresses.City, Addresses.State) AS RowNum 
FROM (((Customers INNER JOIN CustomerMembershipXRef ON Customers.CustomerID = CustomerMembershipXRef.CustomerID) INNER JOIN Organizations ON Customers.OrgID = Organizations.OrgID) INNER JOIN (Countries INNER JOIN Addresses ON Countries.CountryID = Addresses.CountryID) ON Customers.CustomerID = Addresses.EntityID) INNER JOIN Memberships ON (Organizations.OrgID = Memberships.OrgID) AND (CustomerMembershipXRef.MembershipID = Memberships.MembershipID))) 
AS PaginatedTable 
WHERE (PaginatedTable.RowNum BETWEEN 15 AND 33) AND ((Memberships.ExpireDate > GETDATE()) AND (Addresses.EntityTypeID=200) AND (Customers.RecordStatus='A') AND (Memberships.RecordStatus='A') AND(Organizations.OrgTypeID=46 OR Organizations.OrgTypeID=55) AND (Addresses.State = 'MI ')) 

错误是“直接执行SQL;无游标。”

+0

什么是确切的错误?我的查询中没有看到任何光标。此外,我建议你谷歌“SQL ROW_NUMBER函数” – 2014-09-25 16:20:37

+0

是啊,这是错误“没有光标”,但我试图使它类似于例子,我可以..我不习惯MS SQL,我不特别关心它,但这个客户使用它,所以我必须弄清楚。 – b747fp 2014-09-25 16:28:04

+0

也许这个查询是一个较大的脚本的一部分?因为您发布的内容无法生成“无游标”错误。 – 2014-09-25 16:40:53

回答

0

在SQL 2012及更高版本中,有很好的OFFSET和FETCH子句作为ORDER BY子句的一部分。

http://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx

然而,由于使用的是SQL 2008,一个解决方案是使用ROW_NUMBER()。

下面,我分页冒险工程数据库中的产品表的记录。

这可以变成一个存储过程并由前端应用程序调用。

真诚

约翰

www.CraftyDba.com

TSQL:

-- PAGE CNT & ITEM CNT 
DECLARE @PAGECNT INT = 5; 
DECLARE @ITEMCNT INT = 50; 

-- USE COMMON TABLE EXPRESSION 
;WITH CTE_PRODUCT AS 
(
SELECT 
    ROW_NUMBER() OVER (ORDER BY NAME) as RID, 
    * 
FROM 
    [AdventureWorks2012].[Production].[Product] P 
) 
SELECT * 
FROM CTE_PRODUCT 
WHERE RID >= @PAGECNT * @ITEMCNT AND RID < (@PAGECNT+1) * @ITEMCNT; 

输出:

enter image description here

b747fp嗨,

你测试你的答案?

我使用公用表表达式(CTE)的原因是,由于处理QUERY的逻辑方式,别名不可用于WHERE子句。

请参阅下文,您的解决方案不起作用!

约翰

enter image description here

0

我理解了它有一些问题的parenthasis和列定义和排序依据位置......这里正在查询

SELECT CountryID,ExpireDate,EntityTypeID,MRecordStatus,CRecordStatus,OrgTypeID,CountryName,FName,LName,EMail,OrgName,OrgURL,City,State,CountryName,Zip 
FROM (
    SELECT Countries.CountryID as CountryID, Countries.Name as CountryName, Customers.FName as FName, Customers.LName as LName, Customers.EMail as EMail, LTRIM(Organizations.OrgName) AS OrgName, Organizations.URL as OrgURL, Addresses.City as City, Memberships.ExpireDate as ExpireDate, Addresses.EntityTypeID as EntityTypeID, Memberships.RecordStatus as MRecordStatus, Organizations.OrgTypeID as OrgTypeID, Customers.RecordStatus as CRecordStatus, Addresses.State as State, Addresses.Zip as Zip, ROW_NUMBER() OVER (ORDER BY LName ASC) AS RowNum 
    FROM((((Customers INNER JOIN CustomerMembershipXRef ON Customers.CustomerID = CustomerMembershipXRef.CustomerID) INNER JOIN Organizations ON Customers.OrgID = Organizations.OrgID) INNER JOIN (Countries INNER JOIN Addresses ON Countries.CountryID = Addresses.CountryID) ON Customers.CustomerID = Addresses.EntityID) INNER JOIN Memberships ON (Organizations.OrgID = Memberships.OrgID) AND (CustomerMembershipXRef.MembershipID = Memberships.MembershipID)) 
    WHERE ExpireDate > GETDATE() AND EntityTypeID=200 AND Customers.RecordStatus='A' AND Memberships.RecordStatus='A' AND (OrgTypeID=46 OR OrgTypeID=55) AND State = 'MI ' 
) 
AS PaginatedTable 
WHERE PaginatedTable.RowNum BETWEEN 150 AND 200