PDA

View Full Version : سوال: مشکل در Inner Join بین چهار جدول؟



پیام حیاتی
چهارشنبه 22 مهر 1394, 19:20 عصر
سلام
این جداول من هستند :

136034


با این کوئری تونستم استان ، شهر و منطقه رو نشون بدم :


select o_name , c_name , m_name from T_Ostan,T_City,T_Mantaghe
where T_Ostan.o_id=T_City.c_o_id and T_City.c_id=T_Mantaghe.m_c_id ;



اما زمانی که جدول (چهارم) املاک رو اضافه می کنم هیچ چیز در خروجی نمایش نمیده :


select o_name , c_name , m_name , * from T_Ostan,T_City,T_Mantaghe,T_Amlak
where T_Ostan.o_id=T_City.c_o_id and T_City.c_id=T_Mantaghe.m_c_id and T_Mantaghe.m_id=T_Amlak.am_m_id ;

پیام حیاتی
پنج شنبه 23 مهر 1394, 11:35 صبح
بروزرسانی....

aslan
پنج شنبه 23 مهر 1394, 12:36 عصر
select * from T_Ostan Inner Join T_City On T_Ostan.o_id=T_City.c_o_id
Inner Join T_Mantaghe On T_City.c_id=T_Mantaghe.m_c_id
Inner Join T_Amlak On T_Mantaghe.m_id=T_Amlak.am_m_id

پیام حیاتی
پنج شنبه 23 مهر 1394, 13:14 عصر
select * from T_Ostan Inner Join T_City On T_Ostan.o_id=T_City.c_o_id
Inner Join T_Mantaghe On T_City.c_id=T_Mantaghe.m_c_id
Inner Join T_Amlak On T_Mantaghe.m_id=T_Amlak.am_m_id

ممنون با این کوئری مشکل حل شد ، الآن اگر بخواهم شرط قرار بدم به چه شکل خواهد شد؟
مثلا" نمایش املاکی که در منطقه m_name و در شهر c_name قرار دارند.
تشکر

aslan
پنج شنبه 23 مهر 1394, 14:49 عصر
استفاده از where در انتهای کوئری ................

crazy_1892
جمعه 24 مهر 1394, 17:49 عصر
دوست عزیز دوستان لطف کردند با استفاده از join زدن به شما پاسخ دادند و بنده هم پیشنهاد می کنم به هیچ وجه از روش ضرب جدول ها استفاده نکنید (روشکه خودتون استفاده کردید)

پیام حیاتی
جمعه 24 مهر 1394, 19:27 عصر
دوست عزیز دوستان لطف کردند با استفاده از join زدن به شما پاسخ دادند و بنده هم پیشنهاد می کنم به هیچ وجه از روش ضرب جدول ها استفاده نکنید (روشکه خودتون استفاده کردید)
سللم
لطفا دلیل استفاده نکردن از این روش رو بفرمائید.

aminmousavi
شنبه 25 مهر 1394, 02:46 صبح
سلام پیام جان . دوست عزیزمون درست میفرمایند نباید از ضرب دکارتی در کوئری نوشتن استفاده کنید .
به دلیل اینکه میزان مقایسه رکوردهای شما بسیار بالا میره و اگه یک دیتابیس با حجم رکورد بالا داشته باشید یک فاجعه است ! دلیل فنی هم در بسیاری از کتاب های پایگاه داده وجود داره ، اما بنده بطور خلاصه یک توضیحی میدم .
کوئری اولت رو فرض کن :

select o_name , c_name , m_name from T_Ostan,T_City,T_Mantaghe
where T_Ostan.o_id=T_City.c_o_id and T_City.c_id=T_Mantaghe.m_c_id ;

مقادیر این جداول فرض کن بشکل زیر باشه :

Ostan :


Name
id


تهران
1


فارس
2







City :


Name
idOstan
id


تهران
1
1


پردیس
1
2


شیراز
2
3



Mantaghe :



Name
idCity
id


منطقه 1 تهران
1
1


منطقه 3 پردیس
2
2


منطقه 7 شیراز
3
3



فقط اون کوئری رو اجرا میکنی همچین جدولی ایجاد میشه : باعث میشه 18 تا رکورد ایجاد بشه و بین اون ها مقایسه بشه ، همین جدولی ایجاد میشه :



Name
idCity
id
Name
idOstan
id
Name
id


منطقه 1 تهران
1
1

تهران
1
1

تهران
1


منطقه 3 پردیس
2
2

تهران
1
1

تهران
1


منطقه 7 شیراز
3
3

تهران
1
1

تهران
1


منطقه 1 تهران
1
1
پردیس
1
2

تهران
1


منطقه 3 پردیس
2
2
پردیس
1
2

تهران
1


منطقه 7 شیراز
3
3
پردیس
1
2

تهران
1


منطقه 1 تهران
1
1
شیراز
2
3

تهران
1


منطقه 3 پردیس
2
2
شیراز
2
3

تهران
1


منطقه 7 شیراز
3
3
شیراز
2
3

تهران
1



این که نوشتم فقط نصف رکوردها بود ، برای استان شیراز هم 9 تا رکورد ساخته میشه که کلا میشه 18 تا ! اگر دقت کنی میبنی بیشتر رکوردها بدون معنی هستن ، و هیچ رابطه ای ندارن . بین این 8 تا فقط دو تا رکورد هستن که معنی دارن . اما چرا اینجوری شد ؟
دلیلش اینکه در کوئری نوشتن باید قبل join کردن تعداد رکورد ها رو کاهش بدین ، تو این کوئری میگین کل رکورد های این 3 تا جدول join بشن بعد بگردیم دنبال مقدار درست (نسبت به کلید خارجی و اصلی)! اما وقتی شما inner joiin یا ... استفاده میکنید رکوردهای اضافی رو اجازه نمیدین ایجاد بشن ، مستقیما قبل از join شدن میگین کلیدهای اصلی که کلید خارجی شون در جدول دیگر هست واکشی بشن .

پیام حیاتی
شنبه 25 مهر 1394, 10:19 صبح
سلام پیام جان . دوست عزیزمون درست میفرمایند نباید از ضرب دکارتی در کوئری نوشتن استفاده کنید .
به دلیل اینکه میزان مقایسه رکوردهای شما بسیار بالا میره و اگه یک دیتابیس با حجم رکورد بالا داشته باشید یک فاجعه است ! دلیل فنی هم در بسیاری از کتاب های پایگاه داده وجود داره ، اما بنده بطور خلاصه یک توضیحی میدم .
کوئری اولت رو فرض کن :

select o_name , c_name , m_name from T_Ostan,T_City,T_Mantaghe
where T_Ostan.o_id=T_City.c_o_id and T_City.c_id=T_Mantaghe.m_c_id ;

مقادیر این جداول فرض کن بشکل زیر باشه :

Ostan :


Name
id


تهران
1


فارس
2







City :


Name
idOstan
id


تهران
1
1


پردیس
1
2


شیراز
2
3



Mantaghe :



Name
idCity
id


منطقه 1 تهران
1
1


منطقه 3 پردیس
2
2


منطقه 7 شیراز
3
3



فقط اون کوئری رو اجرا میکنی همچین جدولی ایجاد میشه : باعث میشه 18 تا رکورد ایجاد بشه و بین اون ها مقایسه بشه ، همین جدولی ایجاد میشه :



Name
idCity
id
Name
idOstan
id
Name
id


منطقه 1 تهران
1
1

تهران
1
1

تهران
1


منطقه 3 پردیس
2
2

تهران
1
1

تهران
1


منطقه 7 شیراز
3
3

تهران
1
1

تهران
1


منطقه 1 تهران
1
1
پردیس
1
2

تهران
1


منطقه 3 پردیس
2
2
پردیس
1
2

تهران
1


منطقه 7 شیراز
3
3
پردیس
1
2

تهران
1


منطقه 1 تهران
1
1
شیراز
2
3

تهران
1


منطقه 3 پردیس
2
2
شیراز
2
3

تهران
1


منطقه 7 شیراز
3
3
شیراز
2
3

تهران
1



این که نوشتم فقط نصف رکوردها بود ، برای استان شیراز هم 9 تا رکورد ساخته میشه که کلا میشه 18 تا ! اگر دقت کنی میبنی بیشتر رکوردها بدون معنی هستن ، و هیچ رابطه ای ندارن . بین این 8 تا فقط دو تا رکورد هستن که معنی دارن . اما چرا اینجوری شد ؟
دلیلش اینکه در کوئری نوشتن باید قبل join کردن تعداد رکورد ها رو کاهش بدین ، تو این کوئری میگین کل رکورد های این 3 تا جدول join بشن بعد بگردیم دنبال مقدار درست (نسبت به کلید خارجی و اصلی)! اما وقتی شما inner joiin یا ... استفاده میکنید رکوردهای اضافی رو اجازه نمیدین ایجاد بشن ، مستقیما قبل از join شدن میگین کلیدهای اصلی که کلید خارجی شون در جدول دیگر هست واکشی بشن .

توضیحات مثل همیشه کامل و عالی.ممنون

پیام حیاتی
یک شنبه 26 مهر 1394, 22:43 عصر
در کلیدهای خارجی موجود در جدول املاک نمی توان مقداری را insert کرد به خاطر نیاز به اینکه ملک با کد استان و شهر ثبت بشه فیلدهای am_ostan , am_city رو اضافه کردم ، در نهایت جداول به این شکل شد :

136121

الآن کوئری زیر جواب نمی دهد :


select * from T_Ostan Inner Join T_City On T_Ostan.o_id=T_City.c_o_id
Inner Join T_Mantaghe On T_City.c_id=T_Mantaghe.m_c_id
Inner Join T_Amlak On T_Mantaghe.m_id=T_Amlak.am_m_id



اگر خط آخر را حذف کنم اطلاعات نمایش داده می شود.
مشکل این خط چیست؟


Inner Join T_Amlak On T_Mantaghe.m_id=T_Amlak.am_m_id

notlikeothers
دوشنبه 27 مهر 1394, 08:46 صبح
درود.به جای inner join ,leftjoin بزنید شایددرست شه

پیام حیاتی
دوشنبه 27 مهر 1394, 14:48 عصر
درود.به جای inner join ,leftjoin بزنید شایددرست شه
با left join اطلاعات رو آورد اما باز اطلاعات املاک سلکت نشده.

select * from T_Ostan Left Join T_City On T_Ostan.o_id=T_City.c_o_id
Left Join T_Mantaghe On T_City.c_id=T_Mantaghe.m_c_id
Left Join T_Amlak On T_Mantaghe.m_id=T_Amlak.am_m_id

شیطونه میگه بیخیال نرمال سازی بشیم همه رو بریزیم تو یه جدول کار تمام کنیم :اشتباه:

پیام حیاتی
سه شنبه 28 مهر 1394, 12:41 عصر
دوستان اگر می دونید مشکل غیر منطقی هست و راهی ندارد بفرمائید تا چاره دیگری پیدا کنم.