article

محدودسازی، گروه بندی و مرتب سازی نتایج در MySQL

mysql-order-group

در ادامه آموزش مقدماتی کار با php و mysql، نوبت به آشنایی با نحوه استفاده از دستورات  ORDER BY و GROUP BY رسیده است، با ذکر این مقدمه که دستورات ذکر شده در واقع با هدف دسته بندی و مرتب سازی دقیق تر نتایج و به دست آوردن مقادیر مورد نظر در هنگام کار با php و mysql ایجاد شده اند، به عبارتی دیگر، در برنامه نویسی کاربردی، مواردی پیش می آید که ناگزیریم اطلاعات را به صورت مرتب شده نشان دهیم، یا نتایج مشابه را در یک مورد خلاصه کنیم، اینجاست که کاربرد ORDER BY و GROUP BY رهگشای ما خواهد بود که در ادامه آموزش به آن خواهیم پرداخت.

آموزش در حال بازبینی و ویرایش است...

دستور ORDER BY


همانطور که در مباحث گذشته از آموزش  مقدماتی MySQL به طور مختصر دیدیم، از ORDER BY در یک دستور SELECT * FROM استفاده می شود، هدف از به کاربردن آن، تفهیم نحوه مرتب سازی و چینش سلیقه ای و سفارشی نتایج و ردیف های درخواست شده از mysql است، به فرض اگر کاربرانی با مقادیر سنی متفاوت در سایت خود داشته باشیم و بخواهیم اسامی آنها را بر اساس سن مرتب کنیم، خواهیم نوشت:
<?php 
mysql_query("SELECT * FROM table WHERE name != '' ORDER BY age");
?>
خروجی کد بالا می تواند به فرض به شکل زیر باشد.
Amin 23
Mohammad 24
Maryam 26
.
.
.
همانطور که ملاحظه می کنید، در مثال بالا از جدول table و دو ستون فرضی name و age استفاده کرده ایم.

استفاده از

ASC

،

DESC

و تابع RAND
در حالت پیش فرض، mysql نتایج را به صورت صعودی (از کوچک به بزرگ یا Ascending) مرتب سازی می کند، اما مرتب سازی به صورت نزولی (از بزرگ به کوچک یا Descending) و همچنین مرتب سازی اتفاقی یا رندوم (Random) با افزودن عباراتی که در زیر مشاهده می کنید، امکان پذیر است.
ASC: مرتب سازی پیش فرض یا صعودی (از کوچک به بزرگ)
DESC: مرتب سازی نزولی (از بزرگ به کوچک)
RAND: مرتب سازی به صورت اتفاقی (رندوم)
به مثال های زیر توجه کنید.
نحوه استفاده از ASC برای مرتب سازی و نمایش نتایج به صورت چینش صعودی:
<?php 
mysql_query("SELECT * FROM table WHERE name != '' ORDER BY age ASC");
?>
نحوه استفاده از DESC برای مرتب سازی و نمایش نتایج به صورت چینش نزولی:
<?php 
mysql_query("SELECT * FROM table WHERE name != '' ORDER BY age DESC");
?>
نحوه استفاده از تابع RAND برای مرتب سازی و نمایش نتایج به صورت چینش اتفاقی:
<?php 
mysql_query("SELECT * FROM table WHERE name != '' ORDER BY RAND()");
?>

استفاده از LIMIT


استفاده از دستور ORDER BY به تنهایی و بدون محدود کردن تعداد نتایج، می تواند منجر به نمایش تعداد خیلی زیادی از اطلاعات با یک درخواست از دیتابیس شود، از این رو یک پارامتر دیگر به نام LIMIT را می توانیم به دستور خود اضافه کنیم، LIMIT تعداد ردیف هایی را که به عنوان نتایج یک پرس و جو از دیتابیس به دست می آید، محدود می کند، به فرض دستور زیر:
<?php 
mysql_query("SELECT * FROM table WHERE name != '' ORDER BY RAND() LIMIT 5");
?>
تنها 5 کاربر را به صورت اتفاقی انتخاب می کند، همچنین می توان نقطه شروع انتخاب ردیف ها را نیز به mysql تفهیم کرد، بدین منظور برای LIMIT از دو عدد استفاده می کنیم، عدد اول مقادیر ردیفی است که با توجه به ORDER BY آن را انتخاب کرده ایم (به فرض شروع از سن 35 سال) و عدد دوم تعداد نتایجی است که پرس و جو را به آن محدود کرده ایم (به فرض 5 عدد).
<?php 
mysql_query("SELECT * FROM table WHERE name != '' ORDER BY age ASC LIMIT 35,5");
?>
با استفاده از این شیوه به صورت داینامیک، می توان قابلیت هایی مثل نمایش صفحه به صفحه مطالب را ایجاد نمود که در بحث آموزش های کاربردی در این باره خواهیم گفت.

استفاده از AND و OR


شیوه نگارش (syntax) دستورات php در هنگام کار با mysql این اجازه را به ما می دهد که همانند علامت های && و || از دو عبارت AND و OR در یک query استفاده کنیم، البته نحوه کاربرد آنها در اینجا کمی متفاوت است اما هدف از به کارگیریشان یکی است، از AND برای محدودتر و دقیق تر کردن نتایج و از OR برای وسیع تر کردن شمول نتایج یک پرس و جو استفاده می شود، به فرض اگر بخواهیم فقط کاربران دارای سن بالاتر از 40 و پائین تر از 20 را نمایش دهیم، می نویسیم:
<?php
mysql_query("SELECT * FROM table WHERE name != '' AND (age > 40 OR age < 20) ORDER BY age");
?>
دستور بالا، کاربرانی را که سن آنها بالاتر از 40 یا پائین تر از 20 باشد، در لیست نتایج پرس و جو از پایگاه داده نمایش می دهد.
نکته: استفاده از علامت های پرانتز () برای گروه بندی و مختصرنویسی پرس و جوهای MySQL کاربرد دارد، در واقع بدون پرانتز پرس و جو به شکل زیر خواهد بود:
mysql_query("SELECT * FROM table WHERE name != '' AND age > 40 OR name != '' AND age < 20 ORDER BY age");

استفاده از GROUP BY


یک قابلیت کاربردی دیگر که در دسته بندی و نمایش بهتر نتایج حاصل از پرس و جوی پایگاه داده می توان از آن استفاده کرد، قابلیت گروه بندی نتایج دارای وجه مشترک در یک نتیجه است، این قابلیت توسط پارامتر GROUP BY به دست می آید، به فرض اگر بخواهیم گروه بندی را بر اساس شهر کاربران داشته باشیم، خواهیم نوشت:
<?php 
mysql_query("SELECT * FROM table WHERE name != '' GROUP BY city ORDER BY age");
?>
به این صورت از بین کاربران یک شهر، تنها یک عضو با توجه به نحوه چینش دستور ORDER BY انتخاب شده و در نتایج نشان داده می شود.
مثال دیگر از کاربرد GROUP BY در mysql:
<?php 
mysql_query("SELECT id,name,age FROM table WHERE name NOT LIKE '%Akbar%' GROUP BY city ORDER BY age ASC LIMIT 5");
?>
در هنگام استفاده از قابلیت GROUP BY و ORDER BY باید دقت کنید که از آنها به ترتیب استفاده شود، در غیر اینصورت mysql خطای syntax را نمایش خواهد داد.
توابع مربوط به GROUP BY را در اصطلاح توابع تجمعی یا aggregate functions می گویند (شامل COUNT، MAX، MIN، SUM، AVG و...) که در آموزش های بعدی به تفصیل در مورد آنها خواهیم گفت.
sectionدسته بندی: آموزش مقدماتی » MySQL
related مطالب بیشتر:
» استفاده از WHERE در پرس و جوی MySQL
» آموزش MySQL، سیستم مدیریت پایگاه داده
» توابع تجمعی (Aggregate Functions) در MySQL
» استفاده از JOIN و ساخت پرس و جوی ترکیبی در MySQL
» به روز رسانی ردیف ها در MySQL با UPDATE
commentنظرات (۲۵ یادداشت برای این مطلب ارسال شده است)
more یادداشت های جدید بر اساس تاریخ ارسال در انتهای یادداشت های موجود نمایش داده می شوند.
نویسنده: ansherli
۲۲:۴۲ ۱۳۹۱/۱۱/۲۸
سلام
ببخشید من می خواستم بدونم چطور میشه تعداد پست ها رو محدود کرد مثلا توی یه صفحه 10 تا پست قرار بگیره
و پایین صفحه به این صورت باشه
prev 1 2 3 4 5 … 74 next
توی مطالب سایت خیلی گشتم ولی نتونستم پیدا کنم .
ممنون میشم راهنماییم کنید.
پاسخ: 
سلام
این مورد هنوز در آموزش های سایت منتشر نشده.
به دلیل (کمی) پیچیده بودن مبحث، واقعا امکان طرح آن در این قسمت نیست و نیاز به توضیح کامل دارد، لذا یا باید منتظر انتشار آن در مطالب آینده باشید یا اینکه در وب جستجو کنید.
نویسنده: حسین
۱۹:۲۹ ۱۳۹۲/۰۵/۰۷
یه دنیا باز ممنونم.
امیدوارم لبتون خندون باشه.
نویسنده: شکوفه
۱۳:۰۱ ۱۳۹۲/۰۶/۳۰
ممنون از آموزشهای خوبتون
نویسنده: masiha68
۱۴:۳۵ ۱۳۹۲/۰۷/۱۵
طبق معمول ... فوق العاده
نویسنده: خلیل
۲۰:۳۹ ۱۳۹۲/۰۷/۳۰
خیلی ممنون
نویسنده: سيد عباس
۱۶:۰۶ ۱۳۹۲/۰۸/۰۶
دوست واستاد گرامي سلام من يه كد دارم ميخوام وقتي مثلا مطلب جديدي پست ميكنم بياد اول در كد زير بايد چه تغييري بدم لازم به ذكر است با پست هر مطلب اطلاعات جدول از قديمي به جديد نمايش داده ميشه ميخوام در واقع برعكس اين بشه يعني هر پستي كه ارسال ميكنم بياد اول جدول
حذف شد
چه تغييري بايد در كد بالا بدم؟؟؟
از شما ممنون !!! لازم به ذكره با كمك هاي شما تا حالا تونستم يك مديريت محتواي ساده راه اندازي كنم.
با تشكر اوس
پاسخ: 
سلام
هرچند پاسخ دقیق به سوال شما نیاز به بررسی آنلاین تغییرات در خروجی دارد، اما به نظر با استفاده از ORDER BY و ASC یا DESC می توانید این کار را انجام دهید:
$query_Recordset1 = "SELECT * FROM page_index ORDER BY id ASC";
نکته: ستون id می تواند در جدول شما نام دیگری داشه باشد (معمولا id شماره یکتای هر مطلب از کوچکتر به بزرگتر است).
نویسنده: علی امینی
۱۳:۲۰ ۱۳۹۲/۰۸/۰۹
با سلام
واقعا دستتون درد نکنه.
الان که بیشتر دقت میکنم میبینم که تو آموزش شما بهترین هستید.
واقعا کارتون عالیه.
ایشالا همیشه موفق باشید
یا علی
نویسنده: مهران
۱۶:۴۴ ۱۳۹۳/۰۲/۲۱
سلام خسته نباشید.
من با دستور LIMIT تعداد رکورد های دریافتی رو 10 قرار دادم. حالا سوال اینه اگر قصد دسترسی به 10 رکورد بعدی رو داشته باشم باید چیکار کنم؟؟ و به همین ترتیب..
ممنون میشم راهنماییم کنید.
پاسخ: 
سلام
لطفا مطلب را با دقت مطالعه کنید، دستور LIMIT دو پارامتر دارد، در صورتی که هر دو پارامتر تنظیم شود، عدد اول نقطه شروع انتخاب ردیف ها و عدد دوم تعداد آنها است، برای کسب اطلاعات بیشتر، عبارت "صفحه بندی" را در قسمت جستجوی سایت وارد کنید.
نویسنده: علی احمدی
۱۴:۱۹ ۱۳۹۳/۱۲/۲۵
سلام
این دستور رو نوشتم ولی زمانی که داده ها نمایش داده میشوند باز مرتب نشون نمیده
$res=mysql_query("select * from sabt where id=$id Order By id");
پاسخ: 
سلام
در پرس و جو از علامت = استفاده شده و این یعنی تنها یک مقدار مورد نظر است (در این حالت تنها یک ID یا ID های مشابه انتخاب می شوند)، که چینش در چنین حالتی ممکن نیست!
نویسنده: علی احمدی
۱۱:۲۱ ۱۳۹۳/۱۲/۲۶
سلام دوباره
بدون شرط هم امتحان کردم ولی باز مرتب نمیکنه طرز صحیح نوشتن کد با شرط و بدون شرط رو اگه ممکنه بهم بگین. ممنون
res=mysql_query("select * from sabt  Order By id");
پاسخ: 
سلام
به نظر مشکل دیگری در برنامه یا دیتابیس شما وجود دارد، اگر ID به صورت INT باشد و مقادیر آن متفاوت، اصولا باید چینش در یکی از حالت های آموزش داده شده صورت گیرد.
نویسنده: علی احمدی
۱۴:۱۷ ۱۳۹۴/۰۱/۱۰
با سلامی دوباره
مشکل اینجا بود که id از نوع int نبود. حل شد. خیلی خیلی ممنون از لطف شما
نویسنده: کارجو
۱۷:۳۰ ۱۳۹۴/۰۶/۱۱
ممنون. خیلی مفید بود.
نویسنده: نیما
۰۰:۵۰ ۱۳۹۴/۱۰/۲۴
با سلام چرا وقتی از rand دقیقا مثل آموزش شما استفاده میکتم به من اخطار syntax میده
دقیقا این
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'rand()' at line 1
پاسخ: 
سلام
در این قسمت یک اشکال جزئی وجود داشت که با یادآوری شما اصلاح شد!، از نمونه کد فعلی استفاده کنید.
نویسنده: اکبر
۰۰:۱۲ ۱۳۹۷/۰۵/۲۰
$pdo = new PDO(dsn, username, password);
if(isset($_POST['Rotbe'])){
$stmt = $pdo -> query( ' SELECT * FROM Emtiyazat ORDER BY Score DESC LIMIT 10 ');

$a = array ();
$loop = 1;

while($row = $stmt->fetch ()){
array_push($a, array('Name' . $loop => $row['Name'], 'Score' . $loop => $row['Score']));
$loop++;
}

echo json_encode($a);
$pdo = null;
}
با سلام خدمت استاد عزیز
کد بالا درست کار میکنه و طبق دستور نام و امتیازات ده نفر اول جدول بر اساس id را ارسال میکنه و در برنامه در یک تکست نشان میدهد مشکل همین است تمام اسمها را در یک تکست نشان میدهد من اگر بخواهم نام نفر اول را و دوم را و سوم را و تا ده هر کدام را جدا جدا بفرستت باید چه دستوری اضافه کنم
در اینجا Name1 تمامی اسمها را دریافت میکند مثلا چه دستوری بنویسم که Name1 نام نفر اول جدول طبق id بگیرد و مثلا Name2 نام نفر دوم و الی اخر
ممنون از سایت خوبتون
پاسخ: 
با توجه به توضیحات برنامه شما در این بخش شامل دو قسمت می شود، قسمت اول وظیفه ایجاد خروجی اولیه را دارد که کد آن را درج کرده اید و مطابق با نیازتان آن را ویرایش کرده ایم، اما قسمت دوم نحوه استفاده از این خروجی اولیه جهت ایجاد نتیجه نهایی برای سمت کاربر است که کدهای این قسمت برایمان مشخص نیست و قاعدتا ممکن است متناسب با تغییرات اعمال شده به درستی کارایی نداشته باشد و قاعدتا باید این قسمت نیز ویرایش شود.
نویسنده: اکبر
۲۱:۵۵ ۱۳۹۷/۰۵/۲۰
با سلام مجدد دوست عزیز اون قسمتی که شما ویرایش کردید نیازی به ویرایش نداره چون درست کار میکنه مشکل اینجاست که نیم هر پنج اسم از جدول را می فرسته اما میخوام یک اسم بفرسته با یه مشخصه که تو برنامه اسم یک را تو یه تکست و اسم دو را تو یه تکست دیگه نشون بدم این همه پنج اسم رو باهم می فرسته و نمیشه جدا سازی کرد نمیدونم منظورم رو گرفتین یا نه به طور خلاصه چطور میتونم برای خروجی ليميت پنج متغیر بسازم که متغیر اول نام ليميت یک را ارسال کنه متغیر دوم نام ليميت دوم را و الی آخر نمیدونم متوجه شدید منظورم رو یا نه
پاسخ: 
همان طور که گفتیم به کدهای شما دسترسی نداریم تا ببینیم خروجی نهایی به چه نحوی تجزیه و چاپ می شود، در کل با قرار دادن تمام آیتم ها در یک آرایه می توان آنها را مورد به مورد تجزیه کرد، کد فعلی شما خروجی به شکل نمونه زیر ایجاد می کند:
Array
(
[0] => Array
(
[Name1] => 1
[Score1] => 1
)
)
بر همین اساس راه حل پیشنهادی ایجاد خروجی به صورت نمونه آرایه زیر بود (کد ویرایش شده خروجی مشابه این آرایه تولید می کند):
Array
(
[0] => Array
(
[Name1] => 1
[Score1] => 1
)
[1] => Array
(
[Name2] => 2
[Score2] => 2
)
[2] => Array
(
[Name3] => 3
[Score3] => 3
)
[3] => Array
(
[Name4] => 4
[Score4] => 4
)
)
اگر با آرایه ها در PHP آشنا باشید می توانید از این خروجی هر طور که مورد نیاز است استفاده کنید، البته احتمالا باید کدهای قسمت چاپ نتیجه نیز ویرایش شوند، اگر نتوانید از این آرایه استفاده کنید صرفا با دسترسی و امکان تست کدها است که می توان مشکل را رفع کرد.
more لطفا پیش از ارسال یادداشت نکات زیر را مد نظر داشته باشید:
- مواردی که به کلی خارج از موضوع این مطلب هستند را در فرم منوی "تماس با ما" مطرح و پاسخ را از طریق ایمیل دریافت کنید.
- به سوالات کلی، مبهم، غیرضروری و مشکلاتی که تلاشی برای رفع آن نکرده باشید پاسخ کوتاه و مختصر داده خواهد شد!
- کدها و اسکریپت های طولانی را ترجیحا در یک صفحه وب آنلاین قرار دهید تا امکان تست و بررسی وجود داشته باشد.
- تمام یادداشت ها بررسی و برای هر کاربر زمان مشخصی جهت پاسخگویی در نظر گرفته می شود، لطفا از طرح سوالات متعدد در بازه زمانی کوتاه خودداری کنید.





6 × 6
 refresh
آخرین دیدگاه ها
more برای دسترسی سریع به یادداشت مربوطه می توانید از لینک مطلب در کادر زیر استفاده کنید.
form نبی
در:
‏asc و desc رو جابجا نوشتی
۱۳۹۹/۰۷/۰۴

form ساناز محمدی
در:
سلام مرسی از کدی که گذاشتید ♥
۱۳۹۹/۰۷/۰۳

form mahtab
در:
سلام خسته نباشین ببخشید میخواستم بپرسم که چجوری میتونیم یه کلیپ رو از کامپیوتر از انیستا دانلود کنیم ؟؟ اها اینم بگم...
۱۳۹۹/۰۷/۰۲

form سعید
در:
سلام دستتون درد نکنه از پروژه شما استفاده کردم فقط یه مشکل اگه در یک صفحه دو تا لیست کشویی داشته باشیم چطوری...
۱۳۹۹/۰۷/۰۱

form Iman Mafakheri
در:
سلام من یه قالب خارجی اوردم راست چینش کردم حتی فونتشم تغییر دادم اما متاسفانه وقتی متن فارسی مینویسم حروف رو جدا جدا مینویسه نمیدونم...
۱۳۹۹/۰۶/۳۰

form میثم صدیق
در:
سلام برای اضافه کردن یک المان با (append) من یک کلید گذاشتم اضافه میشه ولی با هر بار کلیک کردن اضافه میشود اگر بخواییم یک...
۱۳۹۹/۰۶/۲۹

form amin
در:
سلام و خسته نباشید می خواستم Slash ( / ) رو به صورت اتوماتیک از تمامی URL ها حذف کنم البته با کمک htaccess...
۱۳۹۹/۰۶/۲۵

form محمد
در:
سلام وقت بخیر من یه همچین کدی دارم میشه لطفا راهنمایی کنید مشکلش چیه؟ سپاسگزارم
۱۳۹۹/۰۶/۲۴

form سروش
در:
سلام . من اطلاعات را از دیتابیس دریافت میکنم و در جدول میبینم . میخوام مثلا 6 مورد آخر را در یک ردیف ببینم و...
۱۳۹۹/۰۶/۲۳

form Behdad kanani
در:
سلام اصلا نمی شه اینکارو انجام داد
۱۳۹۹/۰۶/۲۲

form جعفری
در:
سلام قبل از تبدیل تاریخ نوشتید مثلا خب این مقدار تاریخ برای من در دیتابیس در جدولی بنام startedtm بصورت یونیکس...
۱۳۹۹/۰۶/۲۰

form احمد
در:
با عرض سلام و خسته نباشید ببخشید برای فایل دانلودی باید از چه دستوری استفاده کنم فایل با پسوند pdf رو میخوام بزارم اگر امکانش...
۱۳۹۹/۰۶/۲۰

form شیما
در:
سلام آیا وقتی در قسمت وبلاگ دوستان وبلاگی رو ثبت میکنیم صاحب وبلاگ با استفاده از برنامه های خاصی میتونه متوجه بشه ؟
۱۳۹۹/۰۶/۱۹

form mahtab
در:
سلام خسته نباشین من نمیدونم چرا مدیریت وبم برام باز میشه اما وقتی میزنم مشاهده وب رو میزنم نمیاره واسم فقط امیدوارم هک...
۱۳۹۹/۰۶/۱۸

form ساناز محمدی
در:
سلام دوباره این ساب دامین بنده هست اگر یکی از مطالب را مشاهده کنید هر محصولی که ارسال شده داخل از طریق مدیریت یک...
۱۳۹۹/۰۶/۱۷
form محسن
در:
سلام و عرض ادب مجدد کد زیر هم کار نمیکنه مشکل چی میتونه باشه ؟!
۱۳۹۹/۰۶/۱۶
form ساناز محمدي
در:
سلام بنده یه ساب دامین دارم با دامنه شخصی حالا داخل این ساب دامین طرف آدرس سایت خودش رو داخل ساب دامین بنده میذاره مثلآ...
۱۳۹۹/۰۶/۱۶
form محسن
در:
سلام و عرض ادب لطفا راهنمایی کنید مشکل کد زیر چیه
۱۳۹۹/۰۶/۱۶
form احمد
در:
با عرض سلام ببخشید من با دستور append میخوام یه سطری رو به سبدم اضافه کنم ولی چطوری باید داخل append تگ ها رو بنویسم...
۱۳۹۹/۰۶/۱۵
form احمد
در:
با عرض سلام مجدد و خسته نباشید ببخشید طبق فرمایش شما من قبل از دستور else دستور if را نوشته بودم تا جایی که اطلاع...
۱۳۹۹/۰۶/۱۴
form احمد
در:
با سلام ببخشید طریقه استفاده از دستور else در ایجکس به چه صورت هست ایا باید دوباره فانکشن دان رو در هنگام شرط گذاشتن بزارم....
۱۳۹۹/۰۶/۱۳
form مجتهد
در:
سلام ابتدائا از سایت مفیدتون تشکر می کنم. من خیلی از آموزه هام رو از سایت شما یاد گرفتم. یه سوال دارم...
۱۳۹۹/۰۶/۱۳
form محمد حسین
در:
سلام لینک های من وقتی کلیک شوند اررور 404 تولید میکنند. علت چیست؟
۱۳۹۹/۰۶/۱۱
form حسین
در:
سلام بر شما و با تشکر از سایت خوبتون. من ابتدا با تابع mail پیش رفتم و یک if ایجاد کردم که اگر ایمیل...
۱۳۹۹/۰۶/۱۰
form mehdi
در:
خطای -22 مربوط به چیه؟
۱۳۹۹/۰۶/۱۰
  در انتظار بررسی: ۱
 پاسخگویی به سوالات ممکن است تا 24 ساعت زمان ببرد.