PDA

View Full Version : پیشنهاد برای حل این فرمول در sql



shgroup
دوشنبه 02 اسفند 1389, 23:45 عصر
سلام عزیزان
در یک فرمول محاسباتی در برنامه امتیازدهی (مثل بانکها) که به ازای هر 10000 تومان 1 امتیاز داده می شود به این فرمول نیاز دارم. لطفا اگر پیشنهادی برای حل ساده تر آن دارید بفرمایید:
فرض بر این باشد که ما در این برنامه تاریخی را مشخص می کنیم به عنوان مثال بانک اعلام می کند که همه مشتریان باید تا تاریخ 1389/12/01 مبلغ 15000000 تومان در حساب خود سپرده داشته باشند.
حال اگر یک مشتری یک تا دو روز قبل از این تاریخ مبلغ حساب سپرده اش 12000000 تومان بوده و یک روز مانده به پایان این تاریخ مبلغ 5000000 تومان واریز میکند. حال سوال اینجاست که که sql با چه فرمولی باید تنها 3 میلیون از این 5 میلیون را محاسبه امتیاز کند و مابقی را در محاسبه امتیازش منظور نکند ؟! به چه صورت ؟ با چه فرمولی ؟
با چه روشی در sql ؟ :متفکر:
سپاس فراوان

Reza_Yarahmadi
سه شنبه 03 اسفند 1389, 14:38 عصر
اينكار كاملا وابسته به طراحي ديتابيس شما داره و ربطي به فرمول و ... نداره. براي محاسبه امتياز شما بايد اول ليست تراكنش هاي يك حساب رو داشته باشيد. بعد براي هر حساب با استفاده از كرسر از تاريخ ابتداي دوره شروع كنيد و به ازا هر تراكنش امتياز تا تاريخ تراكنش رو محاسبه كنيد. و يا اينكه يك جدول دوم درست كنيد كه به ازا هر تراكنش امتياز حاصل تا تاريخ تراكنش رو محاسبه و توي جدول دوم ذخيره كنه. روش دوم يك مقدار سرعت ثبت تراكنش رو پايين مياره (خيلي محسوس نيست) ولي سرعت محاسبه امتيازات رو بالاميبره.

shgroup
سه شنبه 03 اسفند 1389, 14:57 عصر
اينكار كاملا وابسته به طراحي ديتابيس شما داره و ربطي به فرمول و ... نداره. براي محاسبه امتياز شما بايد اول ليست تراكنش هاي يك حساب رو داشته باشيد. بعد براي هر حساب با استفاده از كرسر از تاريخ ابتداي دوره شروع كنيد و به ازا هر تراكنش امتياز تا تاريخ تراكنش رو محاسبه كنيد. و يا اينكه يك جدول دوم درست كنيد كه به ازا هر تراكنش امتياز حاصل تا تاريخ تراكنش رو محاسبه و توي جدول دوم ذخيره كنه. روش دوم يك مقدار سرعت ثبت تراكنش رو پايين مياره (خيلي محسوس نيست) ولي سرعت محاسبه امتيازات رو بالاميبره.

دوست عزیز از راهنماییتون کاملا سپاسگزارم
خودم به استفاده از cursor خیلی فکر کردم فکر میکنم این راه بهتر باشه - لطفا میشه راهنمایی کنید از cursor در این مثال چطوری باید استفاده کرد؟
بیشترین مشکلم هم سر کم کردن واریزی آخر است؟
متشکرم

Reza_Yarahmadi
سه شنبه 03 اسفند 1389, 15:17 عصر
Select مورد استفاده كرسر رو بر اساس تاريخ مرتب كنيد (Order By) و شرط جستجو رو تاريخ تراكنش بزرگتر از تاريخ شروع امتياز دهي و كوچكتر از تاريخ اتمام امتياز دهي بذاريد.
توي هر واكشي مقدار تاريخ قبلي رو نگه داريد و اختلاف روز ركورد جاري با ركورد قبلي رو با استفاده از توابع موجود SQL بدست بياريد و امتياز اونو محاسبه كنيد. بعد از تموم شدن ركوردها ، تاريخ اتمام امتياز دهي رو از تاريخ آخرين تراكنش كم كنيد و ...
در صورتيكه تعداد كاربران و تعداد تراكنش ها زياد باشه(بيش از چند صد هزار ركورد) اين روش زمان زيادي ميگيره.

shgroup
پنج شنبه 05 اسفند 1389, 12:58 عصر
Select مورد استفاده كرسر رو بر اساس تاريخ مرتب كنيد (Order By) و شرط جستجو رو تاريخ تراكنش بزرگتر از تاريخ شروع امتياز دهي و كوچكتر از تاريخ اتمام امتياز دهي بذاريد.
توي هر واكشي مقدار تاريخ قبلي رو نگه داريد و اختلاف روز ركورد جاري با ركورد قبلي رو با استفاده از توابع موجود SQL بدست بياريد و امتياز اونو محاسبه كنيد. بعد از تموم شدن ركوردها ، تاريخ اتمام امتياز دهي رو از تاريخ آخرين تراكنش كم كنيد و ...
در صورتيكه تعداد كاربران و تعداد تراكنش ها زياد باشه(بيش از چند صد هزار ركورد) اين روش زمان زيادي ميگيره.

سلام
من تلاش کردم که روشی که شما فرمودید رو پیاده سازی کنم اما خیلی مشکل دارم.
امکان داده همین امری که فرمودید را یک مثال ساده بزنید تا من با سینتکس کرسر دراین وضعیت آشنا بشم؟
ممنونم

Reza_Yarahmadi
جمعه 06 اسفند 1389, 11:34 صبح
امکان داده همین امری که فرمودید را یک مثال ساده بزنید تا من با سینتکس کرسر دراین وضعیت آشنا بشم؟
به مثال ساده زیر با نمونه داده های موجود توجه کنید. توی این مثال مقدار موجودی در تاریخ های تراکنش ثبت شده ، حداقل موجودی برای امتیاز دهی 150000 و به ازا هر 50000 یک امتیاز تعلق میگیره.

CREATE TABLE [dbo].[tbl](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Date] [datetime] NULL,
[Amount] [bigint] NULL,
[UserId] [int] NULL
)

Insert Into tbl (UserId, date, Amount) Values (1, '2011.01.01', 150000)
Insert Into tbl (UserId, date, Amount) Values (1, '2011.01.03', 200000)
Insert Into tbl (UserId, date, Amount) Values (1, '2011.01.09', 250000)
Insert Into tbl (UserId, date, Amount) Values (1, '2011.01.11', 170000)
Insert Into tbl (UserId, date, Amount) Values (1, '2011.01.21', 90000)
Insert Into tbl (UserId, date, Amount) Values (1, '2011.01.25', 180000)
Insert Into tbl (UserId, date, Amount) Values (1, '2011.02.11', 20000)


Declare
@UserId int,
@OldAmount bigint,
@Amount bigint,
@EndDate datetime,
@Date datetime,
@OldDate datetime,
@point int
Set @OldAmount = 0
Set @point = 0
Set @EndDate = '2011.02.01'
Set @OldDate = '2010.12.31'

Declare _cursor Cursor For
Select UserId, Amount, Date From tbl Where Date Between @OldDate AND @EndDate order by date
Open _cursor
Fetch Next From _cursor Into @UserId, @Amount, @Date
Set @OldAmount = @Amount
While (@@Fetch_Status = 0)
Begin
Declare @days int
Set @days = DATEDIFF(day, @OldDate, @Date)
Set @Point = @Point + (
@days * (
Case When (@OldAmount - 150000) > 0 Then
((@OldAmount - 150000) / 50000) + 1
Else 0 END
)
)
Select @OldDate as OldDate, @Date as Date, @Days as days, @Point as Point, @OldAmount as OldAmount, @Amount as Amount
Set @OldDate = @Date
Set @OldAmount = @Amount
Fetch Next From _cursor Into @UserId, @Amount, @Date
End
IF(@Date < @EndDate)
Begin
Set @days = DATEDIFF(day, @Date, @EndDate)
Set @Point = @Point + (
@days * (
Case When (@OldAmount - 150000) > 0 Then
((@OldAmount - 150000) / 50000) + 1
Else 0 END
)
)
End
Select @point as Point
Close _cursor
Deallocate _cursor


Drop Table tbl

mojtaba888
سه شنبه 24 بهمن 1391, 14:45 عصر
سلام
من هم یه سوال مثل دوست عزیزمان داشتم اما با یک تفاوت
در سیستم امتیاز دهی مثل بانک ) به ازای هر یک میلیون تومان در 24 ساعت 1 امتیاز بدهد به طور مثال :
شخصی امروز 1 میلیون تومان واریز می کند و پس از 24 ساعت 1 امتیاز به او داده می شود و 1 روز بعد (یعنی روز سوم) مبلغ 1 میلیون تومان واریز می کند و پس از 24 ساعت 1 امتیاز دوباره به او داده می شود.
او در مجموع 2 میلیون واریز کرد و طی این چهار روز 4 امتیاز کسب کرد .
لطفا یک مثال ساده از این برنامه را بگویید
با تشکر