مقاله : بدست آوردن رتبه برای لیست نمرات دانش آموزان

Iauksh
به نام خدا
می خواهم رتبه ای برای دانش آموزان بدست بیاورم هر دانش آموز نمره ای دارد و در ضمن امکان نمره تکراری هم وجود دارد.
حالا با استفاده از SQL این کار را چطور انجام دهم آیا عملی هست.
اگر کسی راه دیگه ای هم غیر SQL سراغ داره ممنون می شوم کمکم کنه

Iauksh
سلام

یه راه ( به غیر از SQL ) اینه:



adoquery1.sql.text:=': select * forom table_ name order by nomre DESC';

while not adoquery1.eof do
begin
adoquery1.edit;
adoquery1.fieldvalues['rotbe']:=adoquery1.recno;
adoquery1.post;
adoquery1.next;
end;

Iauksh
امید خان خیلی ممنون
اون طوری که من فهمیدم اول لیست نمرات را مرتب یا Sort می کنی.
بعد از همان اول تا آخر شماره رکورد را در فیلد مربوط به رتبه قرار می دهی.
اما امید جان به نظرت اگه سه نفر نمره یکسان داشته باشند باز هم رتبه این سه نفر یکسان است.و درست جواب می ده

Iauksh

Iauksh
با سلام
فکر کنم اگر از GroupBy استفاده کنیم مشکل نمره های تکراری حل شود اما توی Group by نمیشه Update کرد :(
اما اگر یه توی کد امید دست کاری کنیم و یه if و یه متغییر بگذاریم جواب میده.
اما باز یه مشکل دیگه هست هنگام Update کردن نمرات از دوباره باید این کار انجام بشود.
کسی فرمولی سراغ نداره توش چند تا عدد بریزیم یه رتبه به ما بده :lol:

Iauksh

Iauksh
من این مشکل رو در SQL Server حل کردم ولی مطمئن نیستم در Database های دیگه هم کار کنه. من یک جدول داشتم به نام Students که دو فیلد یکی ID و دیگری Grade رو داشت که Grade نمره دانش آموزان بود و رتبه اونا هم به این شکل محاسبه میشه



Select (Select Count(Distinct S1.Grade) From Students S1 Where S1.Grade>S2.Grade) + 1 As TotalGrade, S2.Grade From Students S2 Group By S2.Grade Order By S2.Grade DESC

Iauksh
این یکی یه کم مطمئنتر و ساده تره من در SQL از این استفاده می کنم

select Top=(Select Count(Distinct b) from Table1
Where b>=W.b ),
a,b
From Table1 w
order by 1

در این کدها جدولی با نام Table1 با دو فیلد a و b که قرار است فیلد b آن را رتبه دهی کنیم و بنام top نمایش دهیم مشکل تکراری هم ندارد

Iauksh
با سلام
دوست عزیز ممنون از اینکه با حوصله جواب میدید .
من اون کد بالا رو تو اکسس هر چی امتحان کردم ولی نشد . اگه ممکنه یه بانک رو تو اکسس درست کن و اونو بذار دان لود کنیم . البته می بخشبد ها . اگه زحمتی نیست . ممنون از لطفتون .

Iauksh
آقای مهدی
زحمت تبدیل این کار را Delphi Area کشیده اند.
توی قسمت الگوریتم ها نوشته شده است

Iauksh
با سلام
دوستان عزیز من هر چی کار کردم نتونستم تو اکسس ای کد رو اجرا کنم اگه ممکنه توی یه بانک ساده اینو اجرا کنید و بذارید بانک رو دان لود کنیم .
خیلی ممنون : جوجه وی بی کار دی بی کار

Iauksh

Iauksh
با استفاده از دو دستور Select در داخل هم، می شه رتبه را برای هر نفر حساب کرد. ولی اینکه به ازای بدست آوردن رتبه هر دانش آموز، یک Select انجام شود، زمان زیادی گرفته می شه ( تعداد زیادی رکورد مثلا 10 هزار یا بیشتر، با داده های Random تولید کنید و این دستور رو امتحان کنین)
به نظر من اگر یک فیلد رتبه به جدول اضافه کنین و در داخل Trigger های Delete، Update و Insert این فیلد رو Update کنین، خیلی بهتر باشه. چون این طوری هنگام گرفتن Select هیچ زمان اضافی تری مصرف نمی شه.
نوشتن Trigger ها، نیز کاری مشکلی نیست و زمان اجرای کمی هم دارند.

نظر بقیه دوستان ... ؟

Iauksh

Iauksh
به نظر من اگر یک فیلد رتبه به جدول اضافه کنین
ایا به نظر شما جدول ما نرمالیزه است .با یه Update کوچولو توی نمرات باید کل نمرات از دوباره update شوند

Iauksh
دستور Update با شرط ای که گذاشته می شه ( به ازای نمراتی که از یک مقدار خاص بیشتر هستند ) خیلی سریع انجام می شه.
درسته که با اضافه کردن این فیلد جدول شما، نرمال ترین حالت رو نخواهد داشت ولی سرعت گزارش گیری رو به حداقل می رسونه ( البته اگر سرعت براتون مهم باشه ) و در این مورد خاص، فکر نمی کنم باعث از بین رفتن منطق برنامه بشه.
توجه داشته باشین با روشی که شما انجام دادین به ازای هر رکورد در جدول(در هر بار گزارش گیری) باید بر روی تمام رکورد ها Select گرفته بشه، که با اضافه شدن رکورد ها، زمان شما سیر صعودی زیادی خواهد داشت!
می تونین با ایجاد رکورد های random امتحان کنین.

Iauksh
شیما
برای هر اضافه کردن نمره یا حذف کردن نمره یا آپدیت کردن نمره کل فیلد رتبه باید از دوباره update شود
سرعت بخوره توی سرش :lol:
بانک هم نرمال نیست
:shock:

Iauksh
معمولا وقتی نمره ای وارد می شه، خیلی به ندرت پیش میاد که حذف و یا ویرایش بشه.
در روشی که من پیشنهاد کردم ... هر زمان که یک نمره وارد می شه، یک بار بر روی جدول ( حداکثر به تعداد تمام رکورد ها ) عمل ویرایش انجام می گیره، اگر Trigger های صحیحی نوشته باشین هیچ زمان مشکل خاصی بوجود نمیاد و زمان گزارش گیری اون هم


O(n)

هست.ولی در روش شما زمان


O(n^2)

است.

فرض کنین فقط 10000 رکورد دارین، با Select ای که شما می گیرین 10001 بار باید برروی تمام جدول Select گرفته بشه . در صورتی که شما می تونین این تعداد رو به 1 بار کاهش بدین!!!

انتخابش با شماست ...

Iauksh
معمولا وقتی نمره ای وارد می شه، خیلی به ندرت پیش میاد که حذف و یا ویرایش بشه.

دانش اموز a نمره 15 رتبه 1
دانش اموز b نمره 12 رتبه 2
دانش اموز c نمره 10 رتبه 3
دانش اموز d نمره 8 رتبه 4
با اضافه کردن دانش اموز e با نمره 17 رتبه تمام دانش آموز ها باید اپدیت بشه
اما با اضافه کردن دانش اموز f با نمره 2 فقط یک نمره اضافه می شود

در مورد ()O به نکته جالبی اشاره کردید.

خیلی ممنون.