T-SQL split result into two rows - sql-server

I'm building a customer statement report and have the below query.
SELECT TOP (100) PERCENT dbo.vCustomerTransactions.datTrans AS InvDate
,dbo.vCustomerTransactions.strDocRef
,SUM(dbo.vCustomerTransactions.intAmountTax) AS Debit
,ISNULL(dbo.Cashbook.strTransRef, 'None') AS strTransRef
,ISNULL(SUM(dbo.Cashbook.intAmount), 0) AS Credit
,ISNULL(dbo.Cashbook.datCaptured, 0) AS PaymentDate
FROM dbo.vCustomerTransactions
LEFT OUTER JOIN dbo.Cashbook ON dbo.vCustomerTransactions.strDocID = dbo.Cashbook.strDocID
WHERE dbo.vCustomerTransactions.datTrans BETWEEN '2020-02-01 00:00:00'
AND '2020-03-18 00:00:00'
AND dbo.vCustomerTransactions.strTransType IN ('INV')
GROUP BY dbo.vCustomerTransactions.strDocRef
,dbo.Cashbook.strTransRef
,dbo.vCustomerTransactions.datTrans
,dbo.Cashbook.datCaptured
ORDER BY dbo.Cashbook.strTransRef DESC
,dbo.vCustomerTransactions.datTrans
The data is returned as follows.
"2020-02-29 00:00:00" "INV0034004" "1236.7675" "RCPT0007790" "1236.77" "2020-03-10 00:00:00"
What i need to do for that report is split that 1 row into two result rows, as follows
"2020-02-29 00:00:00" "INV0034004" "1236.7675" "0.00"
"2020-03-10 00:00:00" "RCPT0007790" "0.00" "1236.77"
So its splitting the data into debts and credits. I have no idea how to achieve this, please could someone point me in the right direction.
Many Thanks.

I'm making some guesses here, especially in regards that if Credit or Debit has a value of 0 you don't want the row, however using VALUES would likely be better here. It would certainly avoid the overhead of 2 scans of the tables, and the costly UNION (rather than UNION ALL):
WITH CTE AS(
--3 part naming for columns is being removed from SQL Server,. Don't use it.
SELECT --Removed Top, as pointless
CT.datTrans AS InvDate,
CT.strDocRef,
SUM(CT.intAmountTax) AS Debit,
ISNULL(Cb.strTransRef, 'None') AS strTransRef,
ISNULL(SUM(Cb.intAmount), 0) AS Credit,
ISNULL(Cb.datCaptured, 0) AS PaymentDate
FROM dbo.vCustomerTransactions CT
LEFT OUTER JOIN dbo.Cashbook Cb ON CT.strDocID = Cb.strDocID
WHERE CT.datTrans BETWEEN '2020-02-01T00:00:00' AND '2020-03-18T00:00:00'
AND CT.strTransType IN ('INV')
GROUP BY CT.strDocRef,
Cb.strTransRef,
CT.datTrans,
Cb.datCaptured)
SELECT C.InvDate,
C.strDocRef,
V.Debit,
C.strTransRef,
V.Credit,
C.PaymentDate
FROM CTE C
CROSS APPLY (VALUES (0, C.Debit),
(C.Credit, 0)) V (Credit, Debit)
WHERE NOT(V.Debit = 0 AND V.Credit = 0)
ORDER BY C.strTransRef DESC,
C.InvDate;

My approach would be to take the original query and make it into a Common Table Expression (or a temporary table if you want to do it the old school way). And then do two queries - one for credits and one for debits - off of that resultset and UNION them together. Something like this:
WITH cteMain AS (
SELECT TOP (100) PERCENT dbo.vCustomerTransactions.datTrans AS InvDate
,dbo.vCustomerTransactions.strDocRef
,SUM(dbo.vCustomerTransactions.intAmountTax) AS Debit
,ISNULL(dbo.Cashbook.strTransRef, 'None') AS strTransRef
,ISNULL(SUM(dbo.Cashbook.intAmount), 0) AS Credit
,ISNULL(dbo.Cashbook.datCaptured, 0) AS PaymentDate
FROM dbo.vCustomerTransactions
LEFT OUTER JOIN dbo.Cashbook ON dbo.vCustomerTransactions.strDocID = dbo.Cashbook.strDocID
WHERE dbo.vCustomerTransactions.datTrans BETWEEN '2020-02-01 00:00:00'
AND '2020-03-18 00:00:00'
AND dbo.vCustomerTransactions.strTransType IN ('INV')
GROUP BY dbo.vCustomerTransactions.strDocRef
,dbo.Cashbook.strTransRef
,dbo.vCustomerTransactions.datTrans
,dbo.Cashbook.datCaptured
)
SELECT InvDate AS TheDate, strDocRef AS TheRef, Debit, 0.0 AS Credit
FROM cteMain
UNION
SELECT PaymentDate AS TheDate, strTransRef AS TheRef, 0.00 AS Debit, Credit
FROM cteMain
You might also need a WHERE Debit > 0.00 and WHERE Credit > 0.0 in those two SELECT statements, to only pick up the credits/debits that have values, depending on your needs.

Related

Two IDs matching one causing duplicates

I am trying to inner join however I keep getting this duplicate pop up where there are two job IDs matching one Invoice ID (inner joined with a middle table that links both).
I want to only get 1 invoice id and summing the total despite 2 job ids matching it.
Basically there is AINVOICEID (table:Invoice ) matching ABINVOICEID (table:INLines) and inside the INLines table, it contains ARJOBID that matches the JOBID in Jobs.
Select distinct sum(totalBASE) as InvoiceTotal,
DATEADD(MONTH, DATEDIFF(MONTH, 0, InvDate), 0)
from (select distinct left(JOBID,5)as JOBID
from jobs
group by JOBID
) jobs
inner join (select distinct ABINVOICEID, left(ARLJOBID,5) as arljobid
from INLines
group by ARLJOBID, ABINVOICEID
) INLines
on left(ARLJOBID,5) = left(JOBID,5)
inner join (select distinct AINVOICEID
, sum(totalBASE) as totalBASE
, InvDate
from Invoice
group by AINVOICEID, InvDate
) Invoice
on AINVOICEID = ABINVOICEID
where left(JOBID ,5)=left(ARLJOBID,5) and AINVOICEID = ABINVOICEID
and InvDate between '05/01/2022' AND '05/31/2022'
group by left(JOBID ,5), DATEADD(MONTH, DATEDIFF(MONTH, 0, InvDate), 0)
It is quite difficult to try and make sense of what you're asking without an example of the output that you're getting and what the expected output is.
However, I think you're wanting something like this:
SELECT I.AINVOICEID, SUM(I.totalBASE) AS totalBASE, InvDate
FROM Invoice I INNER JOIN
(
SELECT L.ABINVOICEID, J.JOBID
FROM INLines L INNER JOIN
Jobs J ON L.ARLJOBID = J.JOBID
GROUP BY L.ABINVOICEID, J.JOBID
) LJ ON I.AINVOICEID = L.ABINVOICEID
WHERE I.InvDate BETWEEN '05/01/2022' AND '05/31/2022'
GROUP BY I.AINVOICEID, InvDate
This is based on what your SQL query which doesn't really look like it needs to JOIN on the INLines or Jobs table because you're getting everything you need from the Invoice table in the SELECT ?
If this isn't what you're after, if you can elaborate a bit more, then the community on here should be able to better assist with your question.

"not contained in either an aggregate function or the GROUP BY clause" error

I am having problems figuring out how to solve the following error when trying to combine two queries:
Msg 8120, Level 16, State 1, Line 3
Column 'dbo.tbl_Person.perMailingLabel' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Any help in understanding why this is happening and a solution would be greatly appreciated!
WITH AgeData AS
(
SELECT p.perMailingLabel,
p.perDOB,
DATEDIFF(YEAR, p.perDOB, GETDATE()) AS [AGE],
sr.strRegion AS 'State Region',
COUNT (*) AS 'State Region Total'
FROM dbo.fnAllEmails(1) AS e
INNER JOIN tbl_Subscription AS s
ON s.subsubscription_ID = e.MembershipId
INNER JOIN dbo.tbl_Person AS P
ON s.perPerson_ID = p.perPerson_ID
INNER JOIN dbo.tbl_Address AS a
ON s.perPerson_ID = a.perPerson_ID
INNER JOIN dbo.val_StateRegion AS sr
ON sr.strState_ID = a.strState_ID
WHERE s.subsubscription_ID
IN (000001,
000007,
000016,
000150,
000287,
000305,
000337,
000535,
000541,
000651
)
AND a.addPrimaryAdd = 1),
GroupAge AS
(
SELECT p.perMailingLabel,
p.perDOB,
Age,
CASE
WHEN AGE < 30 THEN 'Under 30'
WHEN AGE BETWEEN 31 AND 40 THEN '31 - 40'
WHEN AGE BETWEEN 41 AND 50 THEN '41 - 50'
WHEN AGE > 50 THEN 'Over 50'
ELSE 'Invalid Birthdate'
END AS [Age Groups]
FROM AgeData
)
SELECT COUNT(*) AS [AgeGrpCount],
[Age Groups]
FROM GroupAge
GROUP BY [Age Groups]
ORDER BY AgeGrpCount DESC;
As mentioned in a comment to your question, you're missing a group by clause to correspond with your count(*) in the AgeData CTE. If you still don't understand why this is required, just read up further onit.
If you do see the issue and it was a goof that you just couldn't see, then the deeper issue causing you to miss it may be your code organization. I made the following changes to your code that may help you catch things like this in the future:
I added a group by clause in the AgeData CTE with the relevant columns.
I moved your calculation of 'Age' into a cross apply statement of the first CTE. This allows elimination of the second CTE entirely. I then pointed your base query to the first CTE.
Case statements operate in sequential order, so the 'between' approach can be converted to a simple '<=' approach. This is very optional and you may find 'between' more readable. However, unless an age of 30 is an invalid birth date, you'll want to reform your logic to account for it. I did in my revision.
Your in statement has numbers with leading 0's in them. I imagine in this case the values are really stored as strings. So I converted your numbers to strings to make this clear.
You mix quoted identifiers with bracketed identifiers. I chose one for consistency. I also changed from value as fieldName to fieldName = value, but this is just preference. I just like to see the fieldNames first. But not all SQL dialects allow this.
I changed your inner join statements to simple join statements. Again, just a matter of preference but just demonstrating that it's the same thing.
Of course, the code is untested, so it may have something off here or there, but you get the idea. And it would be much easier to catch some of the issues identified with this or some other better organized structure. Here's the code:
with AgeData as (
select p.perMailingLabel,
p.perDOB,
ap.AGE,
[Age Groups] =
case
when age <= 30 then '30 or under'
when age <= 40 then '31 - 40'
when age <= 50 then '41 - 50'
when age > 50 then 'Over 50'
else 'Invalid Birthdate'
end,
[State Region] = sr.strRegion,
[State Region Total] = count(*)
from dbo.fnAllEmails(1) e
join tbl_Subscription s on s.subsubscription_ID = e.MembershipId
join tbl_Person p on s.perPerson_ID = p.perPerson_ID
join tbl_Address a on s.perPerson_ID = a.perPerson_ID
join val_StateRegion sr on sr.strState_ID = a.strState_ID
cross apply (select age = datediff(year, p.perDOB, getdate())) ap
where a.addPrimaryAdd = 1
and s.subsubscription_ID in (
'000001', '000007', '000016', '000150', '000287',
'000305', '000337', '000535', '000541', '000651'
)
group by p.perMailingLabel,
p.perDOB,
ap.AGE,
sr.strRegion
)
select AgeGrpCount = count(*),
[Age Groups]
from ageData
group by [Age Groups]
order by AgeGrpCount desc;

SQL NESTED JOIN ISSUES

I'm having a heck of a time getting my query to work properly. I have 3 tables (ORDERS, ORDERSITEMS, ORDERPAYMENTS) that I'm trying to build a report for monthly sales taxes due which will look like this:
MONTH YEAR TOTAL RECEIPTS EXEMPT RECEIPTS NON-EXEMPT RECEIPTS SALES TAX
1 2020 $5,000 $4,500 $500 $31.25
TOTAL RECEIPTS: To get this number you have to add together all of the C.OrderPayments_Amount for the given time frame, in this case MONTH(C.OrderPayments_Date) = 1 AND YEAR(C.OrderPayments_Date) = 2020
EXEMPT RECEIPTS: You have to determine if an item is taxable (eg. digital files are not sales taxable, physical prints are). To get this you have determine if the item is taxable by checking the B.OrdersItems_ItemChargeSalesTax. If this field is 0 it does not get charged sales tax and if it is 1 then it does. You then have to filter to only get ORDERSITEMS for the Jan 2020 time frame using by grouping by the C.OrderPayments_Date column that have the B.OrdersItems_ItemChargeSalesTax = 0 and finally add the B.OrdersItems_Total together.
NON-EXEMPT RECEIPTS: To get this number you do the same exact thing for EXEMPT RECEIPTS above except you look for B.OrdersItems_ItemChargeSalesTax = 1 and add the B.OrdersItems_Total together.
SALES TAX: To get this number you use the same date filter as before MONTH(C.OrderPayments_Date) = 1 AND YEAR(C.OrderPayments_Date) = 2020 and then add the A.Order_SalesTax column together.
The first query I have listed is working fine to bring me the total taxes paid and the total income for the month (right now I have hard coded the WHERE statement but that is going to be applied via filters on my list page). What I
need to get from the ORDERSITEMS table is a field called ORDERSITEMS_ItemTotal and sum that field so it is a single line entry on the query. I have seen another person do a nested join. Any suggestions would be greatly appreciated.
**ORDERS TABLE "A"**
Order_ID,
Order_SalesTax,
stateTaxAbbreviation
**ORDERSITEMS TABLE "B"**
Order_FK,
OrdersItems_ItemChargeSalesTax,
OrdersItems_Total
NOTE: In the ORDERSITEMS table a single Order_FK may appear several times as there can be many items on an order
**ORDERPAYMENTS TABLE "C"**
Order_FK,
OrderPayments_PaymentDate,
OrderPayments_Amount
NOTE: In the ORDERPAYMENTS table a single Order_FK may appear several times as there can be multiple payments on an order
While writing this out it seems to be an easy task but when I attempt to put it all together the numbers are wrong because it is adding entries multiple times because there are multiple items on an order and thus it is adding the total payment every time.
Here is the code that I've been tinkering with and I would really appreciate any guidance. Thank you in advance and hopefully I've explained my situation clearly enough.
Select
a.stateTaxAbbreviation AS StateAbbr,
MONTH(c.OrderPayments_Date) AS PaymentMonth,
YEAR(c.OrderPayments_Date) AS PaymentYear,
SUM(c.OrderPayments_Amount) AS TotalPayments,
SUM(a.Order_SalesTax) AS sales_tax
FROM dbo.ORDERS a
INNER JOIN ORDERPAYMENTS as c ON c.Order_FK = a.Order_ID
LEFT OUTER JOIN ORDERITEMS b on b.Order_FK = a.Order_ID
WHERE a.stateTaxAbbreviation = 'MA' AND Month(b.OrderPayments_Date) = 1 AND YEAR(b.OrderPayments_Date) = 2020
GROUP BY stateTaxAbbreviation , MONTH(c.OrderPayments_Date), Year(c.OrderPayments_Date)
You should probably write 2 queries, one where you join the ORDERPAYMENTS table, and another where you join the ORDERITEMS table. Then you can combine them with UNION ALL.
Something like this:
SELECT StateAbbr,PaymentMonth,PaymentYear,SUM(TotalPayments),SUM(sales_tax),SUM(OrdersItems_Total)
FROM (
Select
a.stateTaxAbbreviation AS StateAbbr,
MONTH(c.OrderPayments_Date) AS PaymentMonth,
YEAR(c.OrderPayments_Date) AS PaymentYear,
SUM(c.OrderPayments_Amount) AS TotalPayments,
SUM(a.Order_SalesTax) AS sales_tax,
0 as OrdersItems_Total
FROM dbo.ORDERS a
INNER JOIN ORDERPAYMENTS as c ON c.Order_FK = a.Order_ID
WHERE a.stateTaxAbbreviation = 'MA' AND Month(c.OrderPayments_Date) = 1 AND YEAR(c.OrderPayments_Date) = 2020
GROUP BY stateTaxAbbreviation , MONTH(c.OrderPayments_Date), Year(c.OrderPayments_Date)
UNION ALL
Select
a.stateTaxAbbreviation AS StateAbbr,
MONTH(c.OrderPayments_Date) AS PaymentMonth,
YEAR(c.OrderPayments_Date) AS PaymentYear,
0 AS TotalPayments,
0 AS sales_tax,
SUM(B.OrdersItems_Total) as OrdersItems_Total
FROM dbo.ORDERS a
INNER JOIN ORDERITEMS b on b.Order_FK = a.Order_ID
WHERE a.stateTaxAbbreviation = 'MA' AND Month(b.OrderPayments_Date) = 1 AND YEAR(b.OrderPayments_Date) = 2020
GROUP BY stateTaxAbbreviation , MONTH(c.OrderPayments_Date), Year(c.OrderPayments_Date)
)t
GROUP BY StateAbbr,PaymentMonth,PaymentYear
Thanks to Wouter for pointing me in the right direction. After looking at his suggestion I went back and evaluated what I needed and I create the solution that worked that was based on his idea. Thanks for your patience Wouter, your insight helped a lot!
Select StateAbbr, OrderYear, OrderMonth, SUM(TotalSales) As TotalSales, SUM(TotalSales)-SUM(TaxableRevenue) As ExemptRevenue, SUM(TaxableRevenue) As TaxableRevenue, SUM(SalesTax) As SalesTax
FROM (
Select
/*Get Total Sales and Total Sales Tax Collected*/
a.stateTaxAbbreviation AS StateAbbr,
MONTH(a.Order_Date) As OrderMonth,
YEAR(a.Order_Date) As OrderYear,
SUM((a.Order_TotalBaseSale + a.Order_Shipping) - (((a.Order_PercentDiscount*a.Order_TotalBaseSale)/100) + a.Order_DollarDiscount)) As TotalSales,
SUM(0) As ExemptRevenue,
Sum(0) As TaxableRevenue,
SUM(a.Order_SalesTax) AS SalesTax
FROM dbo.ORDERS a
WHERE a.Order_Status != 'Cancelled'
Group By a.stateTaxAbbreviation, MONTH(a.Order_Date), YEAR(a.Order_Date)
UNION ALL
Select
/*GET EXEMPT ORDERS*/
a.stateTaxAbbreviation AS StateAbbr,
MONTH(a.Order_Date) As OrderMonth,
YEAR(a.Order_Date) As OrderYear,
Sum(0) As TotalSales,
Sum(OrdersItems_ItemTotal) AS ExemptRevenue,
Sum(0) AS TaxableRevenue,
Sum(0) As SalesTax
FROM ORDERSITEMS b
LEFT JOIN ORDERS a ON Order_ID = b.Order_FK
WHERE b.OrdersItems_ItemChargeSalesTax = 0 and a.Order_Status != 'Cancelled'
Group By a.stateTaxAbbreviation, MONTH(a.Order_Date), YEAR(a.Order_Date)
UNION ALL
Select
/*GET NON-EXEMPT ORDERS*/
a.stateTaxAbbreviation AS StateAbbr,
MONTH(a.Order_Date) As OrderMonth,
YEAR(a.Order_Date) As OrderYear,
SUM(0) As TotalSales,
SUM(0) AS ExemptRevenue,
Sum(OrdersItems_ItemTotal) AS TaxableRevenue,
Sum(0) As SalesTax
FROM ORDERSITEMS b
LEFT JOIN ORDERS a ON Order_ID = b.Order_FK
WHERE b.OrdersItems_ItemChargeSalesTax <> 0 and a.Order_Status != 'Cancelled'
Group By a.stateTaxAbbreviation, MONTH(a.Order_Date), YEAR(a.Order_Date)
)t
GROUP BY StateAbbr, OrderMonth, OrderYear
ORDER BY StateAbbr ASC, OrderYear DESC, OrderMonth ASC

Calculate the datediff() between the date 1 and 2

I need to calculate the datediff from one column where the in time marked with a 1 and the out time marked with a 2. if an employee swiped in and there is no out or out but there was no in i would like it to show as null.
I am not sure how I go about doing this.
SELECT
u.userid
,et.name
,CASE
WHEN scs.FullName is NULL THEN u.name
WHEN scs.FullName is NOT NULL THEN scs.FullName
END AS name
,e.LoggedTime AS SwipeTime
,CASE
WHEN et.name = 'Output On By Door' OR et.name = 'User Granted
Entry To Door Using Reading Device' THEN 1
ELSE 2
END AS SwipeTimeDiff
,d.name AS Door
FROM [Users] AS u
LEFT JOIN [Events] AS e ON e.RecordIndex1=u.UserID
LEFT JOIN [EventTypes] AS et on e.EventTypeID = et.EventTypeID
join .[Doors] AS d ON e.RecordIndex2 = d.DoorID
LEFT join SecurityContractorSignIn as scs on scs.Badge = u.lastname
WHERE LoggedTime > CONVERT(DATE, GETDATE()) and d.doorid in (32, 50, 42, 51, 33)
ORDER BY u.name,e.LoggedTime DESC
I would like to have a computed column with the time difference in days, hours and minutes or null if if there is a missing in(1) or out(2) time.
Well, the DATEDIFF() function is fully explained here and the difference for the specific datepart you want to extract is returned as an integer.
According to your need you may do something like but you will have the information in three (or more - if you want to extend) different columns:
-- Calculate the difference of how many days have passed
SELECT DATEDIFF(DAY, LoginTime, LogoutTime) AS DaysPassed
-- Calculate the difference of how many hours have passed
SELECT DATEDIFF(HOUR, LoginTime, LogoutTime) AS HoursPassed
-- Calculate the difference of how minutes have passed
SELECT DATEDIFF(MINUTE, LoginTime, LogoutTime) AS MinutesPassed
If you want to return a string whether the employee logged out or not you may use something like:
SELECT ISNULL(CONVERT(nvarchar(50), DATEDIFF(MONTH, '2019-01-04', NULL)), 'No logout')

Get absolute T-SQL row number where filtering does not affect row number

Currently, I have a sql script which grabs a couple hundred thousand records and I want to page through the data.
Paging works for the most part but my problem is when filtering my results from a subquery which gets the row number, the row number effectively always starts at 1 when what I want it to do is return the row number it was assigned during the sub-query (if that makes sense).
What I have is:
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
So just to kind of describe what is going on, #Start, #End, and #KeyIndex are input parameters.
#Start/#End = Start/End At Row (Which works just fine; starts and ends where I need it to be if #KeyIndex is 0)
#KeyIndex = Start where PrimaryKey > #KeyIndex (which is where the row number becomes an issue).
I think what may be going on is that records before #KeyIndex are not being calculated but I cannot see why that is since the subquery is what holds the row number and I assume it's processed prior to the parent query finishing ?
where (MyDerivedTable.Num BETWEEN #Start AND #End)
AND FulfillmentID > #KeyIndex
order by FulfillmentID
Any suggestions ?
You do know AND FulfillmentID > #KeyIndex is also in your subquery?
Records before #KeyIndex are not being calculated because you told it not to process those records.

Resources