ParsX.com
پذیرش پروژه از دانشجویی ... تا سازمانی 09376225339
 
   ProfileProfile   Log in to check your private messagesLog in to check your private messages  |  FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups Log inLog in   RegisterRegister 

جزوه تركيب جداول در دستور SELECT تاريخ 12/9/1383

 
Post new topic   Reply to topic    ParsX.com Forum Index -> اس . كيو . ال SQL
View previous topic :: View next topic  
Author Message
vahid
بي تو هرگز


Joined: 26 Nov 2004
Posts: 3067
Location: Tehran

PostPosted: Thu Dec 02, 2004 11:58 pm    Post subject: جزوه تركيب جداول در دستور SELECT تاريخ 12/9/1383 Reply with quote

SELECT stno,Avg(grade) FROM grade GROUP BY  stno HAVING count(*)>2

دستور فوق باعث ميشود كه
1. فيلد يا ستون يا همان خصيصه كه هر سه يكي هستند كه براي راحتي كار از نام فيلد استفاده ميكنيم . بنابراين فيلد stno را از جدول grade انتخاب ميكند .
2. avg(grade) يكي از توابع جمعي است وظيفه اين تابع خروجي دادن ميانگين مقداريست كه درون اين تابع قرار ميگيرد در صورت بالا داخل اين تابع از grade استفاده كرده ايم يعني ميانگين نمرات يا grade ها را حساب كن .
3. با استفاده از group by كه در اين دستور استفاده از ان بدليل حضور يك تابع جمعي و نام فيلد با يكديگر گروه بندي بايد بر اساس Stno قرار بگيرد . بنابراين ميانگين بر اساس شماره دانشجويي كه همان stno است انجام ميپذيرد .
4. استفاده از دستور HAVING منجر به ورود شرط در دستور فوق ميشود اين شرط مرتبط با دستور group by است . اين شرط باعث ميشود كه عمليات تابع avg محدود شود . اگر فرض كنيم كه چيزي به نام تابع جمعي نداشتيم ميتوانيم انرا با where مقايسه كنيم چراكه دقيقا مانند Where به اعمال شرط در دستورات ميپردازد . شرط ورودي بر اين دستور coun(*)>2 است بنابراين تعداد كليه ركوردها شمرده ميشود ركوردي كه تكرار ان بر اساس stno بيشتر از 2 مورد بود در خروجي چاپ ميشود . يعني ميانگين نمراتي از دانشجويان را ميبينيم كه در جدول حداقل 3 نمره دارند .
بنابراين ميتوانيد بعد از شرط having دوباره از يكي از توابع شرطي استفاده كنيد . فرضا براي مثال فوق اگر خواستيد معدل دانشجوياني را حساب كنيد كه نمرات انها بيشتر از 15 بوده است ميتوانيد از max(grade)>15 استفاده كنيد .
سوال: تقاضايي بنويسيد كه شماره دانشجويي stno و نام fname و نام خانوادگي lname و نمرات grade هر دانشجو را در خروجي نمايش دهد !
در مرحله اول ظاهرا دستور به شرح زير است :
select stno,fname,lname,grade from student,grade

دستور فوق يك تفاوت اساسي با ديگر دستورات sql كه تا كنون استفاده كرده بوديم دارد و ان اينكه بعد از form به جاي نام يك جدول نام دو جدول امده است ! و اين به ان دليل است كه در جدول student فيلدي براي grade نداشته ايم بنابراين ان را از جدول grade انتخاب كرده ايم . اول از همه روشن كنيم كه مشكل اساسي دستور زير چيست !
دستور فوق همانطور كه ميبينيد از دو جدول student و grade استفاده كرده است اما مشكل اينجاست كه فيلدهايي كه بعد از دستور select انتخاب كرده ايم همگي در جداول مربوط به خودشان قابل تشخيص هستند جز Stno ميدانيم كه فيلد Stno هم در جدول student قرار دارد هم در جدول grade بنابراين بايد مشخص كنيم كه اين stno مربوط به كدام يكي از اين جداول است پس دستور فوق را به صورت زير تصحيح ميكنيم :
select student.stno,fname,lname,grade from student,grade

براي مشخص كردن انكه stno مربوط به كدام جدول است با اوردن نام جدول قبل از نام stno و يك نقطه بلافاصله بعد از ان مشخص شد كه stno از جدول student است .
اما مشكل دومي كه دستور فوق دارد انستكه دستور فوق تنها يك خروجي ساده از فيلدهاي انتخابي بيرون ميدهد . ميدانيد كه دستور Select تنها وظيفه انتخاب فيلدها از جداول مربوطه را دارد اينكه اين فيلدها چگونه به يكديگر مرتبط هستند و ايا اينكه ترتيب اين فيلدها بر اساس ركورد هاي جدول است يا خير بر عهده اين دستور نيست . بنابراين بايد به سراغ دستورات شرطي رفت !
براي انكه مشخط كنيم كه كدام دانش اموزان كدام نمرات را گرفته اند بايد محدوديتي اعمال كنيم بر اينكه چون جدول grade يك جدول جداگانه است بنابراين بايد به طوري ترتيبي بين اين دو ايجاد كرد . ترتيب را ميتوان از همان مشكل اول كه گفته شد به دست اورد اينكه : همانطور كه ديديد فيلد مشترك اين دو جدول stno بود بنابراين ميتوانيم شرطي بگذاريم كه تنها فيلدهايي را نشان بدهد كه شماره دانشجويي stno انها يكسان است ! اين يكساني منجر به ان ميشود كه :
1. ميدانيم Stno در جدول student يك كليد اصلي است بنابراين هر شماره دانشجويي تنها يك نام و نام خانوادگي دارد .
2. در مورد جدول grade ميدانيم نمرات هر كدام به شماره هاي دانشجويي مرتبط با خودشان مرتبط هستند بنابراين هر شماره دانشجويي تنها نمرات خاص خودش را دارد .
حال براي انكه در خروجي ما نمرات و شماره دانشجويي و نام خانوادگي همگي با همديگر مرتبط باشند بايد مقايسه اي بين اين دو جدول انجام دهيم مقايسه به اينصورت است شماره دانشجويي هر جدول با جدول ديگر چك ميشود در صورتي كه شماره دانشجويي ها برابر بود محتويات با يكديگر تركيب ميشوند و بصورت ركوردهايي از جدول در خروجي چاپ ميشوند .
دستور صحيح سوال فوق به صورت زير است
SELECT student.stno,fname,lname,grade from student,grade where student.stno=grade.stno

اگر كمي در توضيحات فوق بيانديشيد ميتوانيد به اين نكته پي ببريد كه عملا چه اتفاقي مي افتد . در واقع ما با شرط فوق نوعي رابطه بين دو جدول ايجاد كرده ايم . رابطه ما به اين صورت است كه هر گاه stno از جدول رئيس كه همان stnudent باشد با stno از جدول grade مطابقت داشت خروجي ها را بر اساسي كه خواسته شده است نمايش بده
اگر به تشريح دستور فوق بپردازيم متوجه ميشويد كه دستور تنها زماني اجرا ميشود كه شماره دانشجويي هر دو جدول يكي باشد .
فرض كنيم شماره دانشجويي 10 نام و نام خانوادگي خود را در جدول student دارد حالا اين شماره دانشجويي با تك تك شماره دانشجويي هاي موجود در جدول grade چك ميشود در صورتيكه به اولين تساوي مقداري رسيد ( يعني به محض رسيدن به اولين شماره دانشجويي كه مطابق با شماره 10 است ) شروع به Select كردن يا انتخاب كردن فيلدهايي كه در جلوي دستور select امده است ميكند يعني student.stno را به همراه fname و lname و grade از جدول student به خروجي چاپ ميكند . سپس به ساغ مقادير بعدي Stno ميرود كه بايد مقايصه شوند .
تذكر : براي چاپ خروجي همانطور كه ميبينيد stno جلوي دستور Select مربوط به جدول student است بنابراين عملا دو شماره دانشجويي يكسان در كنار هم در ركورد نخواهيم داشت .
سوال 2 : شماره دانشجويي نام و فاميلي و دروسي كه دانشجويان گرفته اند را نمايش دهد !
سوال از ما چند فيلد ميخواهد كه در خروجي نمايش دهيم فيلدها به ترتيب stno و fname و lname و name هستند name نام درسي است كه دانشجو گرفته است .
SELECT  stno,fname,lname,name from ????

مرحله اول طي شده است يعني ما فيلدها را انتخاب كرده ايم اما بايد ديد اين فيلدها از كدام جدول انتخاب ميشوند . جدول اولي كه حاوي شماره دانشجويي و نام و نام خانوادگي است جدول student است و جدول دومي كه از ان name يا همان نام درس را گرفته ايم جدول course است . بنابراين داريم
SELECT stno,fname,lname,name FROM student,course

تا اينجا اگر دستور را اجرا كنيم چون از دو جدول متمايز استفاده كرده ايم اطلاعات ما بالطبع طبق همانچه قبلا براي مثال بالا توضيح داده شد بدون هيچ ترتيبي و بدون هيچ ارتباطي است !
بنابراين بايد ارتباطي بين اين دو جدول براي ترتيب دهي پيدا كنيم .
خوب فيلد مشتركي بين اين دو جدول نداريم . اما ميدانيم از طريق جدول ديگري ميتوانيم فيل مشتركي بين اين دو جدول پيدا كنيم . جدول مشترك ما جدول grade است چون ميدانيم دانشجويي كه درسي را برداشته حتما كد درسي كه به صورت كليد اصلي در ان جدول است براي وي مقداري فرض كرده است . بنابراين جدول ديگري را بايد در دستور فوق وارد كنيم .
دستور به صورت زير عوض ميشود
 SELECT stno,fname,lname,name FROM student,course,grade

همانطور كه در دستور فوق ميبينيد جدول grade را نيز به بازي وارد كرديم اما همانطور كه ميدانيم چون در دستور select فيلدي از ان انتخاب نشده است تاثيري بر انچه در خروجي خواهيم داشت بصورت عيني نخواهد داشت . اما به محض وارد كردن جدول grade متوجه اشتراك اين جدول با جدول student از طريق فيلد تكراري Stno خواهيم شد .
خدايا چه كنم !؟
كافيست همانطور كه در مثال قبل توضيح داده شد قبل از فيل انتخابي stno در دستور Select نام جدول مربوط به اين فيلد را بياوريم :

SELECT student.stno,fname,lname,name FROM student,course,grade

اين هم از اين ! اما كار به پايان نرسيده است ما تازه جدول grade را براي ايجاد نوعي اشتراك يا ارتباط بين دو جدول student و course به بازي اورده ايم . بنابراين اشتراك دو جدول قديمي ما مهيا شده است ! به اين صورت كه جدول student از طريق فيلد Stno با جدول grade در ارتباط است و جدول grade از طريق courseno با جدول course در ارتباط است .
بنابراين نوبت به اعمال محدوديت ها ميرسد !
براي اعمال محدوديت بايد اينگونه عمل كنيم كه هرگاه Stno از جدول student با stno از جدول grade هماهنگ شد يا برابر شد سراغ جدول course رفته و فيل هاي courseno با يكديگر چك شوند در صورت ايجاد تساوي بين اين دو نام روبروي نام و نام خانوادگي چاپ شود . اعمال اين ايجاد تساوي را قبل از انكه به جواب نگاه كنيد . ميتوانيد حدث بزنيد ...

SELECT student.stno,fname,lname,name FROM student,course,grade WHERE student.stno=grade.stno and course.courseno=grade.courseno

SELECT student.stno, fname, lname, name
FROM student, course, grade
WHERE student.stno=grade.stno and course.courseno=grade.courseno;

Quote:
All was it

با تشكر از استاد رئوف مكفي
Back to top
Display posts from previous:   
Post new topic   Reply to topic    ParsX.com Forum Index -> اس . كيو . ال SQL All times are GMT + 3.5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum