August 2, 2006 at 4:25 pm
Hi,
I need assistance in setting up a cursor to run in SQL Server 2000. The objective is fairly straight forward and, unfortunately, I'm new to writing cursors.
OBJECTIVE: I have two tables I've generated. The first (table1) lists the cumulative donations made by members from 10/1/2005 through 9/30/2006 along with two datetime columns that are currently NULL. Once column FY500 will display the date in which a member donated over $500 during the time period and the second column will display the date in which the member donated over $1000 during the same time period. The second table lists each time a member made a contribution during the same time period, which may have only been once or up to eight times. Note, the same members (memberIDs) are listed in both tables as a means of creating a join.
The cursor needs to read through the second table (table2) one record at a time performing a cumulative calculation of each donation made for each member. As soon as the cumulative amount for a member reaches $500 with a specific donation, then it needs to insert the data associated with the donation into the FY500 field for that member. It also needs to do the same thing as soon as a donatioin amount equals or exceeds $1000 for the FY1000 field. It is possible that a member may have donated $1000 or more all at once, which will then populate both the FY500 and FY1000 fields at the same time.
Any help or example you can provide would be greatly appreciated.
Thanks,
Grant
August 2, 2006 at 7:19 pm
NO CURSORS!!!
UPDATE Table1
SET FY500 = DT.FY500 ,
FY1000 = DT.FY1000
FROM (
SELECT T1.memberID, T1.PeriodStart, T1.PeriodEnd,
case when SUM(T2.DonatedAmount) >= 500 then 1 else 0 end as FY500 ,
case when SUM(T2.DonatedAmount) >= 1000 then 1 else 0 end as FY1000
FROM Table1 T1
INNER JOIN Table2 T2 ON T1.memberID = T2.memberID
AND T1.Period = T2.Period -- change it according to the way you handle the periods
-- e.g. T2.DonationDoneOnTime BETWEEN T1.PeriodStart AND T1.PeriodEnd
) DT
WHERE DT.memberID = Table1.memberID
AND DT.PeriodStart = Table1.PeriodStart AND DT.PeriodEnd = Table1.PeriodEnd
-- change it according to the way you handle the periods
_____________
Code for TallyGenerator
August 3, 2006 at 8:18 am
I seem to read that you not only want the amounts but the dates these amounts were reached by each donor and I believe you're correct in the fact this is not easy to accomplish as a set operation.
Cursors have their place where nothing else will do, that's why they're included in Sql. That being said try the following general outline. P.S. You'll need to add the code that updates the first donor amount when the condition 'It is possible that a member may have donated $1000 or more all at once, which will then populate both the FY500 and FY1000 fields at the same time.' you spoke of occurs but tht should be trival.
Good Hunting!
declare @DonorID int, @DonationDate smalldatetime, @Donation money
declare DonationList cursor
for
select
DonorID,DonationDate,donation
from
DonationTbl
where
DonationDate
Between
@StartDonationDate
and
@EndDonationDate
order by
DonorID,DonationDate
Open DonationList
Fetch DonationList
into
@DonorID, @DonationDate, @Donation
While @@Fetch_Status=0
begin
if @DonorID<>@LastDonorID
begin
@Sum=@Donation
@LastDonorID=@DonorID
end
else
begin
@Sum=@Sum+@Donation
end
if @Sum >= @LevelOne
begin
Update Tbl set <A href="mailtoonationLevel1=@Sum">DonationLevel1 = @Sum, @DonationDateOne=@DoantionDate
where
<A href="mailtoonorID=@DonorID">DonorID =@DonorID
end
if @Sum >= @LevelTwo
begin
Update Tbl set <A href="mailtoonationLevel2=@Sum">DonationLevel2=@Sum, @DonationDateTwo=@DoantionDate
where
<A href="mailtoonorID=@DonorID">DonorID=@DonorID
end
Fetch DonationList
into
@DonorID, @DonationDate, @Donation
end
close DonationList
deacllocate DonationList
August 3, 2006 at 11:11 am
I appreciate everybody's very valuable help. The cursor is now working. I would have preferred to avoid using a cursor, but it became necessary to use one in order to prevent the date for either field from being updated as additional donations were made that exceeded $1000 and/or $500. For this reason, I had to use the cursor very similar to the one you provided Dan (thanks!)but with a nested check in each of the last two IF statements comparing the Levels. Otherwise, they would continue to update the dates and amounts as the same member continued to make donations.
Thanks again,
Grant
August 3, 2006 at 12:23 pm
Sergiy do you have a cursorless solution for this one?
August 3, 2006 at 6:24 pm
I would probably have a solution if somebody could explain me in plain words ("For dummies" ) what does it mean:
"order to prevent the date for either field from being updated as additional donations were made that exceeded $1000 and/or $500"
_____________
Code for TallyGenerator
August 3, 2006 at 7:05 pm
{insert theme song from Jeopordy here}
--Jeff Moden
Change is inevitable... Change for the better is not.
August 3, 2006 at 11:58 pm
Probably with those dates you mean something like this:
SELECT T1.DonorId, T1.PeriodId, T1.[Date] as DateLimitReached
FROM Table1 T1
INNER JOIN (select DonorId, PeriodId, MAX(Date) as NotYet
from Table2 T
where T.Date < T1.Date
group by DonorId, PeriodId
HAVING SUM(DonationAmount) < 500
) T2 ON T2.DonorId = T1.DonorId and T2.PeriodId = T1.PeriodId
This will return list of periods for every donor when he/she reached the limit of $500.
For every donor only those periods when the limit was reached will be listed.
_____________
Code for TallyGenerator
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply