PDA

View Full Version : Select تو در تو در MySQL



Mohammadrezag
پنج شنبه 27 بهمن 1390, 05:56 صبح
درود بر همه
بنده قبلا برای سایت هام یه جدول جدا برای شاخه و یه جدول برای زیر شاخه می ساختم !
اینبار تصمیم گرفتم توی یه جدول اینکارو بکنم !
دسته های اصلی catid شون میشه 0 ! و دسته های فرعی catid شون میشه ! id اون دسته اصلی ...

حالا من می خوام اینها رو یه جا فراخونی کنم ! به این صورت

شاخه > زیر شاخه
شاخه > زیر شاخه
شاخه > زیر شاخه
شاخه > زیر شاخه
شاخه > زیر شاخه

برای اینکار چه کنم ؟
اگه 2 تاجدول داشتم با join اینکارو می کردم ! اما الان نمی دونم راه حال چیه ! که نخوام تعداد زیادی کوئری بگیرم !

این کوئری catid,title رو بر می گردونه ! من می خوام جای catid تیترش بیاد !


select id,catid,title from ads_category where catid!=0

Reza1607
پنج شنبه 27 بهمن 1390, 16:53 عصر
select tbl.catid,tbl.title,ads_category.title from ads_category as tbl left join ads_category ON tbl.id=ads_category.catid where ads_category.catid!=0

اين رو تست كنيد ببينيد درسته

Mohammadrezag
پنج شنبه 27 بهمن 1390, 17:36 عصر
ممنون که توجه کردین اما
tbl.id که شما نوشتین یعنی یه جدول جدا ... اما یکیه ! توی توضیجاتم نوشتم !

MMSHFE
پنج شنبه 27 بهمن 1390, 18:02 عصر
میگم خوب چرا Select تو در تو؟ چرا از توابع بازگشتی استفاده نمیکنید؟ مثال:


function display($parent = 0, $level = 0) {
$parent = is_numeric($parent) ? (int) $parent : 0;
$level = is_numeric($level) ? (int) $level : 0;
mysql_connect('localhost', 'root', '') or die('Connection error');
mysql_select_db('dbname') or die('Database error');
mysql_query('SET NAMES \'utf8\'');
$parent = mysql_real_escape_string($parent);
$items = mysql_query("SELECT * FROM `table` WHERE (`parent`='{$parent}') ORDER BY `id`");
if($items && mysql_num_rows($items) > 0) {
while($item = mysql_fetch_assoc($items)) {
for($i = 0; $i < $level; $i++) {
echo '&nbsp;&nsbp;&nbsp;&nbsp;';
}
echo $item['text'].'<br/>'.PHP_EOL;
$count = mysql_result(mysql_query("SELECT COUNT(*) AS `count` FROM `table` WHERE (`parent`='{$item['id']}')"), 0, 0);
if($count > 0) {
display($item['id'], $level + 1);
}
}
mysql_free_result($items);
}
}

// Usage:
display();

Mohammadrezag
پنج شنبه 27 بهمن 1390, 19:38 عصر
ممنون ! برای بهینه تر بودن می خوام با یک کوئری این کار رو انجام بدم !

MMSHFE
پنج شنبه 27 بهمن 1390, 19:46 عصر
ازنظر سرعت اجرا، این اسکریپت سریعتر از Select تو در تو اجرا میشه. کلاً بهتره تا جایی که میشه از Selectهای تو در تو پرهیز کنید. موفق باشید.

Mohammadrezag
پنج شنبه 27 بهمن 1390, 19:52 عصر
اینطوری شاید 50 تا کوئری در هر باز کردن صفحه در آن واحد بشه ! مطمئنا یک خط کوئری بهینه تره ! حتی اکه join و select توردتو و ... بشه !

Reza1607
پنج شنبه 27 بهمن 1390, 21:36 عصر
ممنون که توجه کردین اما
tbl.id که شما نوشتین یعنی یه جدول جدا ... اما یکیه ! توی توضیجاتم نوشتم !

دوست عزيز اون tbl يك نام مستعار براي جدولتون هست و نه جدول ديگه

امیـرحسین
پنج شنبه 27 بهمن 1390, 21:39 عصر
این روشها رو ببینید:
SELECT child.id, child.title, child.catid, parents.title AS parent_title FROM ads_category AS child
LEFT JOIN ads_category AS parents ON parent.id=child.catid
WHERE child.catid != 0


SELECT child.id, child.title, child.catid,
(SELECT parents.title FROM ads_category AS parents WHERE parents.id=child.catid) AS parent_title
FROM ads_category AS child WHERE child.catid != 0


SELECT child.id, child.title, child.catid, parent.title AS parent_title FROM ads_category AS child
LEFT JOIN (
SELECT id, title FROM ads_category WHERE catid=0
) AS parents ON parents.id=child.catid
WHERE child.catid != 0
اولی همون روشی هست جناب رضا نوشتند. JOIN با خود جدول کار میکنه. یک روش هم Loop در PHP میشه ۴ تا.
این حالت خاصه باید هر ۴ تا روش رو تست کنید تا ببینید کدوم عملکرد بهتری داره. SubQuery همیشه بد نیست چون MySQL تا حدی که بشه از اجرای کوئری‌های تکراری جلوگیری میکنه.
من حدس میزنم کوئری سومی که من نوشتم نتیجه‌ی بهتری داشته باشه من چنین کوئری رو توی Stored Procedure بزرگ ۱۰۰ خطی استفاده کردم اونهم نه با یک SELECT! و نتیجه‌ی خوبی گرفتم...

Mohammadrezag
پنج شنبه 27 بهمن 1390, 22:08 عصر
فوق العاده بود امیر خان
دست درد نکنه
از دومی استفاده می کنم !

امیـرحسین
پنج شنبه 27 بهمن 1390, 22:18 عصر
تاکید میکنم:

این حالت خاصه باید هر ۴ تا روش رو تست کنید تا ببینید کدوم عملکرد بهتری داره.

Mohammadrezag
پنج شنبه 27 بهمن 1390, 23:04 عصر
تاکید میکنم:

منظورتون از عملکرد سرعتشه ؟!

امیـرحسین
جمعه 28 بهمن 1390, 00:00 صبح
بله قاعدتا!