Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
fan2005
Yak Posting Veteran
85 Posts |
Posted - 2011-01-27 : 13:44:03
|
hi There is a table like one here which has information about all accounts for each date they had transaction, balance is calculated by running total from amount.The dates are in Persian.i want to calculate average of balance for 10 months from 1389/01/01 to 1389/10/01for each account for example (DATEDIFF(dy,'1389/01/01','1389/06/18')*48000+DATEDIFF(dy,'1389/06/18','1389/10/01')*49000)/ DATEDIFF(dy,'1389/01/01','1389/10/01') for 1-11-1but finding the dates is one problemand not supporting datediff() function for persian date is anotherthanks for replytransactionID branchcode customerno PersianDate account AccountID accounttype amount balance1 1 11 1388/10/15 1-11-1 73 1 51000.00 510002 1 11 1388/11/16 1-11-1 73 1 -3000.00 480003 1 11 1389/06/18 1-11-1 73 1 1000.00 490004 1 11 1389/02/11 1-11-2 74 2 65000.00 650005 1 11 1389/06/17 1-12-2 75 2 6000.00 60006 2 12 1389/01/23 2-12-1 76 1 100000.00 1000007 2 12 1389/06/30 2-12-1 76 1 -1000.00 99000 |
|
|
fan2005
Yak Posting Veteran
85 Posts |
Posted - 2011-01-27 : 14:35:07
|
first I want to find balance of max(date) where date<'1389/01/01) for each account.SELECTdistinct C.account, C.balance ,S.maxdate FROMTransactionDetail Cinner join (select distinct MAX(persiandate) as maxdate ,accountfrom TransactionDetailgroup by persiandate,accounthaving MAX(persiandate)<'1389/01/01')Son S.account =C.accountand S.maxdate=C.persiandate this wont give the desired result-----out put-----account balance maxdate1-11-1 48000 1388/11/161-11-1 51000 1388/10/15the result i want is account balance maxdate1-11-1 48000 1388/11/16 |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2011-01-27 : 14:36:45
|
What datatype is column "PersianDate"? N 56°04'39.26"E 12°55'05.63" |
 |
|
|
fan2005
Yak Posting Veteran
85 Posts |
Posted - 2011-01-27 : 14:37:40
|
| nchar(12) |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2011-01-27 : 14:45:47
|
Works fine for me. Why are you using NCHAR(12)? Alter your column to DATE now, please.DECLARE @Sample TABLE ( TransactionID INT, BranchCode INT, CustomerNo INT, PersianDate DATE, Account VARCHAR(6), AccountID INT, AccountType INT, Amount MONEY, Balance MONEY )INSERT @SampleVALUES (1, 1, 11, '1388/10/15', '1-11-1', 73, 1, 51000.00, 51000), (2, 1, 11, '1388/11/16', '1-11-1', 73, 1, -3000.00, 48000), (3, 1, 11, '1389/06/18', '1-11-1', 73, 1, 1000.00, 49000), (4, 1, 11, '1389/02/11', '1-11-2', 74, 2, 65000.00, 65000), (5, 1, 11, '1389/06/17', '1-12-2', 75, 2, 6000.00, 6000), (6, 2, 12, '1389/01/23', '2-12-1', 76, 1, 100000.00, 100000), (7, 2, 12, '1389/06/30', '2-12-1', 76, 1, -1000.00, 99000)SELECT *, DATEDIFF(DAY, '1389/01/01', '1389/06/18') AS PesoFROM @Sample N 56°04'39.26"E 12°55'05.63" |
 |
|
|
fan2005
Yak Posting Veteran
85 Posts |
Posted - 2011-01-27 : 14:50:57
|
quote: Originally posted by Peso Works fine for me. Why are you using NCHAR(12)? Alter your column to DATE now, please.DECLARE @Sample TABLE ( TransactionID INT, BranchCode INT, CustomerNo INT, PersianDate DATE, Account VARCHAR(6), AccountID INT, AccountType INT, Amount MONEY, Balance MONEY )INSERT @SampleVALUES (1, 1, 11, '1388/10/15', '1-11-1', 73, 1, 51000.00, 51000), (2, 1, 11, '1388/11/16', '1-11-1', 73, 1, -3000.00, 48000), (3, 1, 11, '1389/06/18', '1-11-1', 73, 1, 1000.00, 49000), (4, 1, 11, '1389/02/11', '1-11-2', 74, 2, 65000.00, 65000), (5, 1, 11, '1389/06/17', '1-12-2', 75, 2, 6000.00, 6000), (6, 2, 12, '1389/01/23', '2-12-1', 76, 1, 100000.00, 100000), (7, 2, 12, '1389/06/30', '2-12-1', 76, 1, -1000.00, 99000)SELECT *, DATEDIFF(DAY, '1389/01/01', '1389/06/18') AS PesoFROM @Sample N 56°04'39.26"E 12°55'05.63"
First how did you find '1389/06/18'.It should calculate like this(DATEDIFF(dy,'1389/01/01','1389/06/18')*48000+DATEDIFF(dy,'1389/06/18','1389/10/01')*49000)/ DATEDIFF(dy,'1389/01/01','1389/10/01') for 1-11-1which needs you first find 1-11-1 48000 1388/11/16 second persian date is not like christan it would give false resultfor datediff.could you help me in first partfor date diff problem i think i should write a function |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2011-01-27 : 15:01:19
|
So what are the rules for getting the difference in dates for persian dates? N 56°04'39.26"E 12°55'05.63" |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
|
|
fan2005
Yak Posting Veteran
85 Posts |
Posted - 2011-01-27 : 15:05:31
|
| the persain calender is like this12 monthsfrom 1st to 6th months of the 1st half of year it is always 31 daysother 5 month of the 2end half is 30 daysand the last month (12th ) is 29 daysexcept that : every 4 years it is 30 dayswhich this year is called kabiseh in persian language |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2011-01-27 : 15:45:44
|
Yes, exactly as described in the link I posted.Now, which is the 4-year cycle?//Peter N 56°04'39.26"E 12°55'05.63" |
 |
|
|
fan2005
Yak Posting Veteran
85 Posts |
Posted - 2011-01-27 : 18:12:00
|
quote: Originally posted by Peso Yes, exactly as described in the link I posted.Now, which is the 4-year cycle?//Peter N 56°04'39.26"E 12°55'05.63"
declare @IsLeap bit select @IsLeap= case when ( cast((substring (@PDate,1,4))as integer)) % 33 in(1, 5 , 9 , 13 , 17 , 22 , 26 ,30) then 1 ELSE 0 end |
 |
|
|
fan2005
Yak Posting Veteran
85 Posts |
Posted - 2011-01-28 : 03:49:15
|
quote: Originally posted by fan2005 hi There is a table like one here which has information about all accounts for each date they had transaction, balance is calculated by running total from amount.The dates are in Persian.i want to calculate average of balance for 10 months from 1389/01/01 to 1389/10/01for each account for example (DATEDIFF(dy,'1389/01/01','1389/06/18')*48000+DATEDIFF(dy,'1389/06/18','1389/10/01')*49000)/ DATEDIFF(dy,'1389/01/01','1389/10/01') for 1-11-1but finding the dates is one problemand not supporting datediff() function for persian date is anotherthanks for replytransactionID branchcode customerno PersianDate account AccountID accounttype amount balance1 1 11 1388/10/15 1-11-1 73 1 51000.00 510002 1 11 1388/11/16 1-11-1 73 1 -3000.00 480003 1 11 1389/06/18 1-11-1 73 1 1000.00 490004 1 11 1389/02/11 1-11-2 74 2 65000.00 650005 1 11 1389/06/17 1-12-2 75 2 6000.00 60006 2 12 1389/01/23 2-12-1 76 1 100000.00 1000007 2 12 1389/06/30 2-12-1 76 1 -1000.00 99000
--********SOLUTION**********---I solved itany better and faster solution ?--------STEP1alter table TransactionDetail add preBalance decimal(20,0) SET NOCOUNT ON--===== Declare the cursor storage variablesDECLARE @Amount decimal(20,0)DECLARE @CurAccountID bigINT--===== Declare the working variablesDECLARE @PrevAccountID bigINTDECLARE @AccountRunningTotal decimal(20,0)DECLARE @PreAccountRunningTotal decimal(20,0)--===== Create the cursor with rows sorted in the correct -- order to do the running balance by accountDECLARE curRunningTotal CURSOR LOCAL FORWARD_ONLY FOR SELECT AccountID, gardesh FROM dbo.TransactionDetail ORDER BY AccountID, tarikh, TransactionID OPEN curRunningTotal--===== Read the information from the first row of the cursor FETCH NEXT FROM curRunningTotal INTO @CurAccountID, @Amount--===== For each account, update the account running total -- column until we run out of rows. Notice that the -- CASE statement resets the running total at the -- start of each account. WHILE @@FETCH_STATUS = 0 BEGIN --===== Calculate the running total for this row -- and remember this AccountID for the next row SELECT @AccountRunningTotal = CASE WHEN @CurAccountID = @PrevAccountID THEN @AccountRunningTotal + @Amount ELSE @Amount END, @PreAccountRunningTotal = CASE WHEN @CurAccountID = @PrevAccountID THEN @AccountRunningTotal - @Amount ELSE 0 END, @PrevAccountID = @CurAccountID--===== Update the running total for this row UPDATE dbo.TransactionDetail SET balance = @AccountRunningTotal, Prebalance = @PreAccountRunningTotal WHERE CURRENT OF curRunningTotal--===== Read the information from the next row of the cursor FETCH NEXT FROM curRunningTotal INTO @CurAccountID, @Amount END --End of the cursor--======== Housekeeping CLOSE curRunningTotalDEALLOCATE curRunningTotalGOselect * from TransactionDetail------------out put Step1--------transactionID abrnchcod Cfcifno tarikh account AccountID Tbdptype gardesh balance preBalance1 1 11 1388/10/15 1-11-1 97 1 51000.00 51000 02 1 11 1388/11/16 1-11-1 97 1 -3000.00 48000 510003 1 11 1389/06/18 1-11-1 97 1 1000.00 49000 480004 1 11 1389/09/15 1-11-1 97 1 2000.00 51000 490005 1 11 1389/10/02 1-11-1 97 1 1000.00 52000 510006 1 11 1389/02/11 1-11-2 98 2 65000.00 65000 07 1 11 1389/06/17 1-12-2 99 2 6000.00 6000 08 2 12 1389/01/23 2-12-1 100 1 100000.00 100000 09 2 12 1389/06/30 2-12-1 100 1 -1000.00 99000 100000 ----Step2----------drop table a10select * into a10 from TransactionDetail where tarikh between '1389/01/01' and '1389/11/01'order by account , tarikhalter table a10 add sum10 decimal(20,0) CREATE CLUSTERED INDEX IXC_Transaction_AccountID_balance_preBalance_tarikh ON dbo.a10 (AccountID,balance, preBalance,tarikh) SET NOCOUNT ON--===== Declare the cursor storage variablesDECLARE @CurAccountID bigINTDECLARE @preBalance decimal(20,0)Declare @total decimal(20,0) set @total=0DECLARE @Balance decimal(20,0)--===== Declare the working variablesDECLARE @PrevAccountID bigINTDECLARE @Pretarikh nvarchar(12) set @Pretarikh= '1389/01/01'DECLARE @tarikh nvarchar(12)DECLARE @AccountRunningTotal decimal(20,0)DECLARE @PreAccountRunningTotal decimal(20,0)--===== Create the cursor with rows sorted in the correct -- order to do the running balance by accountDECLARE curRunningTotal CURSOR LOCAL FORWARD_ONLY FOR SELECT AccountID, balance ,preBalance,tarikh FROM dbo.a10-- WHERE AccountID <= 10 --Uncomment for "short" testing ORDER BY AccountID, tarikh, TransactionID OPEN curRunningTotal--===== Read the information from the first row of the cursor FETCH NEXT FROM curRunningTotal INTO @CurAccountID,@balance, @prebalance,@tarikh--===== For each account, update the account running total -- column until we run out of rows. Notice that the -- CASE statement resets the running total at the -- start of each account. WHILE @@FETCH_STATUS = 0 BEGIN --===== Calculate the running total for this row -- and remember this AccountID for the next row print(@total)print('+')print(dbo.ShamsiDateDiff(@Pretarikh,@tarikh))print (@Pretarikh)print( '-') print(@tarikh) print ('*') print (@preBalance) print ('=') print(@total+(dbo.ShamsiDateDiff(@Pretarikh,@tarikh))*@preBalance) SELECT @total = CASE WHEN @CurAccountID = @PrevAccountID THEN ((dbo.ShamsiDateDiff(@Pretarikh,@tarikh))*@preBalance) --@AccountRunningTotal + @Amount ELSE case when --@CurAccountID <> @PrevAccountID and @Pretarikh='1389/01/01' then ((dbo.ShamsiDateDiff(@Pretarikh,@tarikh))*@preBalance) else case when @CurAccountID <> @PrevAccountID and @Pretarikh<>'1389/01,01' then 0 END END END, @PrevAccountID = @CurAccountID , @Pretarikh = @tarikh print (@total) --===== Update the running total for this row UPDATE dbo.a10 SET sum10 = @Total WHERE CURRENT OF curRunningTotal--===== Read the information from the next row of the cursor FETCH NEXT FROM curRunningTotal INTO @CurAccountID,@balance, @prebalance,@tarikh END --End of the cursor--======== Housekeeping CLOSE curRunningTotalDEALLOCATE curRunningTotalGOselect * from a10 order by account , tarikh--------output step2transactionID abrnchcod Cfcifno tarikh account AccountID Tbdptype gardesh balance preBalance sum103 1 11 1389/06/18 1-11-1 97 1 1000.00 49000 48000 82560004 1 11 1389/09/15 1-11-1 97 1 2000.00 51000 49000 43120005 1 11 1389/10/02 1-11-1 97 1 1000.00 52000 51000 8670006 1 11 1389/02/11 1-11-2 98 2 65000.00 65000 0 07 1 11 1389/06/17 1-12-2 99 2 6000.00 6000 0 08 2 12 1389/01/23 2-12-1 100 1 100000.00 100000 0 09 2 12 1389/06/30 2-12-1 100 1 -1000.00 99000 100000 16200000 -----------step3declare @totalday int set @totalday= dbo.ShamsiDateDiff('1389/01/01','1389/11/01') select distinct--(SUM(C.sum10)+dbo.ShamsiDateDiff('1398/11/01',S.tarikh1))/11 , C.cfcifnoC.cfcifno,round((diff*C.balance+S.sum1)/@totalday,0) as avg,S.tarikh1,C.balance,S.sum1 from a10 as Cinner join (--select * from a10select distinct C.cfcifno, sum (c.sum10) as sum1 ,C.Tbdptype,dbo.ShamsiDateDiff(max(C.tarikh),'1389/11/01') as diff,max(C.tarikh)as tarikh1--max(C.tarikh) as tarikh1--from dbo.a10 C where C.Tbdptype=1 GROUP BY C.cfcifno,C.Tbdptype)Son S.cfcifno=C.cfcifnoAND C.tarikh=S.tarikh1------------output Step3cfcifno avg tarikh1 balance sum111 48833.000000 1389/10/02 52000 1343500012 92412.000000 1389/06/30 99000 16200000 |
 |
|
|
Ifor
Aged Yak Warrior
700 Posts |
|
|
fan2005
Yak Posting Veteran
85 Posts |
|
|
|
|
|
|
|