به نام خدا
می خواهم رتبه ای برای دانش آموزان بدست بیاورم هر دانش آموز نمره ای دارد و در ضمن امکان نمره تکراری هم وجود دارد.
حالا با استفاده از SQL این کار را چطور انجام دهم آیا عملی هست.
اگر کسی راه دیگه ای هم غیر SQL سراغ داره ممنون می شوم کمکم کنه
به نام خدا
می خواهم رتبه ای برای دانش آموزان بدست بیاورم هر دانش آموز نمره ای دارد و در ضمن امکان نمره تکراری هم وجود دارد.
حالا با استفاده از SQL این کار را چطور انجام دهم آیا عملی هست.
اگر کسی راه دیگه ای هم غیر SQL سراغ داره ممنون می شوم کمکم کنه
سلام
یه راه ( به غیر از SQL ) اینه:
adoquery1.sql.text:=': select * forom table_ name order by nomre DESC';
while not adoquery1.eof do
begin
adoquery1.edit;
adoquery1.fieldvalues['rotbe']:=adoque ry1.recno;
adoquery1.post;
adoquery1.next;
end;
امید خان خیلی ممنون
اون طوری که من فهمیدم اول لیست نمرات را مرتب یا Sort می کنی.
بعد از همان اول تا آخر شماره رکورد را در فیلد مربوط به رتبه قرار می دهی.
اما امید جان به نظرت اگه سه نفر نمره یکسان داشته باشند باز هم رتبه این سه نفر یکسان است.و درست جواب می ده
با سلام
فکر کنم اگر از GroupBy استفاده کنیم مشکل نمره های تکراری حل شود اما توی Group by نمیشه Update کرد :(
اما اگر یه توی کد امید دست کاری کنیم و یه if و یه متغییر بگذاریم جواب میده.
اما باز یه مشکل دیگه هست هنگام Update کردن نمرات از دوباره باید این کار انجام بشود.
کسی فرمولی سراغ نداره توش چند تا عدد بریزیم یه رتبه به ما بده :lol:
از چه نوع Database استفاده میکنید؟
من این مشکل رو در 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
این یکی یه کم مطمئنتر و ساده تره من در 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 نمایش دهیم مشکل تکراری هم ندارد
با سلام
دوست عزیز ممنون از اینکه با حوصله جواب میدید .
من اون کد بالا رو تو اکسس هر چی امتحان کردم ولی نشد . اگه ممکنه یه بانک رو تو اکسس درست کن و اونو بذار دان لود کنیم . البته می بخشبد ها . اگه زحمتی نیست . ممنون از لطفتون .
آقای مهدی
زحمت تبدیل این کار را Delphi Area کشیده اند.
توی قسمت الگوریتم ها نوشته شده است
با سلام
دوستان عزیز من هر چی کار کردم نتونستم تو اکسس ای کد رو اجرا کنم اگه ممکنه توی یه بانک ساده اینو اجرا کنید و بذارید بانک رو دان لود کنیم .
خیلی ممنون : جوجه وی بی کار دی بی کار
احتمالا دوستان کد را برای Transact SQL نوشتن و شما داری توی اکسس که اجرا می کنی نمیشه. توی اکسس کوئری ها Jet-SQL هستن و اینها توی syntax و استفاده از Sub-Query ها با هم اختلاف دارن.
با استفاده از دو دستور Select در داخل هم، می شه رتبه را برای هر نفر حساب کرد. ولی اینکه به ازای بدست آوردن رتبه هر دانش آموز، یک Select انجام شود، زمان زیادی گرفته می شه ( تعداد زیادی رکورد مثلا 10 هزار یا بیشتر، با داده های Random تولید کنید و این دستور رو امتحان کنین)
به نظر من اگر یک فیلد رتبه به جدول اضافه کنین و در داخل Trigger های Delete، Update و Insert این فیلد رو Update کنین، خیلی بهتر باشه. چون این طوری هنگام گرفتن Select هیچ زمان اضافی تری مصرف نمی شه.
نوشتن Trigger ها، نیز کاری مشکلی نیست و زمان اجرای کمی هم دارند.
نظر بقیه دوستان ... ؟
به هر حال باید این کار یک طرف انجام بشه یا زمان وارد کردن اطلاعات یا زمان گرفتن اطلاعات. همون زمانی که شما صرف گرفتن اطلاعات میکنید به همون اندازه و بلکه معمولآ بیشتر صرف بروز رسانی اطلاعات میشه. معمولآ استفاده از Trigger توصیه نمیشه چرا که منطق برنامه در دیتابیس گم میشه ولی اگر سرعت زیاد برای گزارشها لازم هست و اون سرعت در زمان وارد کردن اطلاعات خیلی مهم نیست, استفاده از Trigger بهتره.
ایا به نظر شما جدول ما نرمالیزه است .با یه Update کوچولو توی نمرات باید کل نمرات از دوباره update شوندبه نظر من اگر یک فیلد رتبه به جدول اضافه کنین
دستور Update با شرط ای که گذاشته می شه ( به ازای نمراتی که از یک مقدار خاص بیشتر هستند ) خیلی سریع انجام می شه.
درسته که با اضافه کردن این فیلد جدول شما، نرمال ترین حالت رو نخواهد داشت ولی سرعت گزارش گیری رو به حداقل می رسونه ( البته اگر سرعت براتون مهم باشه ) و در این مورد خاص، فکر نمی کنم باعث از بین رفتن منطق برنامه بشه.
توجه داشته باشین با روشی که شما انجام دادین به ازای هر رکورد در جدول(در هر بار گزارش گیری) باید بر روی تمام رکورد ها Select گرفته بشه، که با اضافه شدن رکورد ها، زمان شما سیر صعودی زیادی خواهد داشت!
می تونین با ایجاد رکورد های random امتحان کنین.
شیما
برای هر اضافه کردن نمره یا حذف کردن نمره یا آپدیت کردن نمره کل فیلد رتبه باید از دوباره update شود
سرعت بخوره توی سرش :lol:
بانک هم نرمال نیست
:shock:
معمولا وقتی نمره ای وارد می شه، خیلی به ندرت پیش میاد که حذف و یا ویرایش بشه.
در روشی که من پیشنهاد کردم ... هر زمان که یک نمره وارد می شه، یک بار بر روی جدول ( حداکثر به تعداد تمام رکورد ها ) عمل ویرایش انجام می گیره، اگر Trigger های صحیحی نوشته باشین هیچ زمان مشکل خاصی بوجود نمیاد و زمان گزارش گیری اون هم
O(n)
هست.ولی در روش شما زمان
O(n^2)
است.
فرض کنین فقط 10000 رکورد دارین، با Select ای که شما می گیرین 10001 بار باید برروی تمام جدول Select گرفته بشه . در صورتی که شما می تونین این تعداد رو به 1 بار کاهش بدین!!!
انتخابش با شماست ...
دانش اموز a نمره 15 رتبه 1معمولا وقتی نمره ای وارد می شه، خیلی به ندرت پیش میاد که حذف و یا ویرایش بشه.
دانش اموز b نمره 12 رتبه 2
دانش اموز c نمره 10 رتبه 3
دانش اموز d نمره 8 رتبه 4
با اضافه کردن دانش اموز e با نمره 17 رتبه تمام دانش آموز ها باید اپدیت بشه
اما با اضافه کردن دانش اموز f با نمره 2 فقط یک نمره اضافه می شود
در مورد ()O به نکته جالبی اشاره کردید.
خیلی ممنون.