获取绝对的T-SQL行号,其中过滤不影响行号

时间:2018-06-22 14:07:20

标签: sql-server tsql

目前,我有一个sql脚本,可抓取数十万条记录,并且我想分页浏览数据。

分页在大多数情况下都是有效的,但是我的问题是,当从一个获取行号的子查询中过滤结果时,当我想要执行的操作是返回在此期间分配的行号时,行号实际上总是从1开始子查询(如果有意义)。

我拥有的是:

SELECT * FROM (
        SELECT DISTINCT --TOP(@End-@Start)
        EF.FulfillmentID
        ,COALESCE(GEN.GroupID, GEL.GroupID) AS GroupID
        ,COALESCE(GEN.GroupName, GEL.GroupName) AS GroupName
        ,EF.PlanEnrollmentID
        ,EF.PlanElectionID
        ,COALESCE(EE2.EmployeeID, EE.EmployeeID) AS EmployeeID
        ,COALESCE(EE2.FirstName, EE.FirstName) AS FirstName
        ,COALESCE(EE2.LastName, EE.LastName) AS LastName
        ,COALESCE(EPE2.BeginDate, EPE.EffectiveDate) AS EffectiveDate
        ,COALESCE(EPE2.EndDate, EPE.TerminationDate) AS TerminationDate
        ,COALESCE(CPEN.CarrierProductID, CPEL.CarrierProductID) AS CarrierProductID
        ,COALESCE(CPEN.CarrierProductName, CPEL.CarrierProductName) AS CarrierProductName
        ,EF.FulFillmentTypeID
        ,FT.FulfillmentTypeDesc
        ,EF.FulfillmentComplete
        ,CAST(EF.RunFulfillment AS BIT) AS RunFulfillment
        ,CAST(@CanModify AS BIT) AS CanModify
        ,ROW_NUMBER() over (order by EF.FulfillmentID) as Num
    FROM
        dbo.E_Fulfillment AS EF
        JOIN appconfig.FulfillmentTypes AS FT ON FT.FulfillmentTypeID=EF.FulFillmentTypeID
        JOIN(
            SELECT
                MAX(FulfillmentID) AS MaxFulfillmentID
            FROM
                dbo.E_Fulfillment
            GROUP BY
                COALESCE(PlanElectionID, PlanEnrollmentID)
            ) AS MX ON MX.MaxFulfillmentID=EF.FulfillmentID

        LEFT JOIN dbo.E_PlanEnrollment AS EPE ON EPE.PlanEnrollmentID=EF.PlanEnrollmentID
        LEFT JOIN dbo.GroupProductPlanOptions AS GPPOEN ON GPPOEN.GroupProductPlanOptionID=EPE.GroupProductPlanOptionID
        LEFT JOIN dbo.GroupProducts AS GPEN ON GPEN.GroupProductID=GPPOEN.GroupProductID
        LEFT JOIN ref.CarrierProducts AS CPEN ON CPEN.CarrierProductID=GPEN.CarrierProductID
        LEFT JOIN dbo.Groups AS GEN ON GEN.GroupID=GPEN.GroupID
        LEFT JOIN dbo.E_Employees EE ON EE.EmployeeID=EPE.EmployeeID

        LEFT JOIN dbo.E_PlanElections AS EPE2 ON EPE2.PlanElectionID=EF.PlanElectionID
        LEFT JOIN dbo.GroupProductPlanOptions AS GPPOEL ON GPPOEL.GroupProductPlanOptionID=EPE2.GroupProductPlanOptionID
        LEFT JOIN dbo.GroupProducts AS GPEL ON GPEL.GroupProductID=GPPOEL.GroupProductID
        LEFT JOIN ref.CarrierProducts AS CPEL ON CPEL.CarrierProductID=GPEL.CarrierProductID
        LEFT JOIN dbo.Groups AS GEL ON GEL.GroupID=GPEL.GroupID
        LEFT JOIN dbo.E_Employees AS EE2 ON EE2.EmployeeID=EPE2.EmployeeID

    WHERE
        ((GEN.GroupID=@GroupID OR GEN.GroupID IS NULL)
        OR (EPE2.EmployeeID=@EmployeeID OR EPE2.EmployeeID IS NULL)
        OR (@GroupID IS NULL AND @EmployeeID IS NULL))
        AND FulfillmentID > @KeyIndex
        ) as MyDerivedTable

        where (MyDerivedTable.Num BETWEEN @Start AND @End)
        AND FulfillmentID > @KeyIndex
        order by FulfillmentID

所以只是为了描述发生了什么,@ Start,@ End和@KeyIndex是输入参数。

@Start/@End =从行开始/结束(这很好用;如果@KeyIndex为0,则在需要的地方开始和结束)

@KeyIndex =从PrimaryKey> @KeyIndex开始(这是行号成为问题的位置)。

我认为可能正在发生的事情是@KeyIndex之前的记录没有被计算出来,但是我看不到为什么,因为子查询保存了行号,并且我认为它是在父查询完成之前处理的。

where (MyDerivedTable.Num BETWEEN @Start AND @End)
AND FulfillmentID > @KeyIndex
order by FulfillmentID

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

您知道AND FulfillmentID > @KeyIndex也在您的子查询中吗?

@KeyIndex之前的记录未计算,因为您告诉它不要处理那些记录。