PDA

View Full Version : این کوئری چطور درست جواب میده؟



hamed_bostan
پنج شنبه 03 آبان 1386, 11:13 صبح
با سلام
من توی یه پروژه به یه مشکلی خوردم که میخوام به ساده ترین و سریع ترین روش حلش کنم که خیلی پروسس نیاز نداشته باشه چون کاربرا زیادن

من 2 تا جدول دارم ROOM و RESERVE_ROOM

جدول ROOM فیلداش مشخصات اتاق های یک هتلن و کلیدش شماره اتاق اون هتل
جدول RESERVE_ROOM فیلداش عبارتند از :
شماره اتاق - تاریخ ورود - تاریخ تخلیه - ساعت ورود - ساعت تخلیه - کد کاربر رزرو کننده اتاق


تعدادی اتاق توی جدول ROOM تعریف شده مثلا اتاق 100 و مشخصاتش که چند تخته هست و اتاق 102 و 102 - هر کدو یه رکورد جدان

بعد توی جدول RESERVE_ROOM بر حسب رزرو درج شده :

اتاف مثلا 100 از تاریخ 01/01/1386 تا تاریخ 15/01/1386 توسط کاربر x رزرو شده
همون اتاق 100 از تاریخ 02/02/1386 تا تاریخ 03/03 /1386 توسط یه کاربر دیگه رزرو شده
و به همین شکل واسه بعصی اتاقای دیگه هم همینطور . شاید اتاقی هم اصلا رزرو نشده باشه

حالا من میخوام اگه کاربری اومد و خواست جستجو کنه که کدوم اتاق در یه بازه زمانی مثلا 02/02/1386 تا 08/03/1386 خالی هست لیست تمام اون شماره اتاقایی رو که در اون بازه رزروی واسه شون نیست یا حتی تداخلی هم توی بازه اونا با یه رزرو دیگه نیست بیاره . اولش فکر میکردم کوئری ساده ای هست و با یه not in حل میشه اما نشد و جواب نداد

ضمنا من تاریخ ها رو فارسی ذخیره کردم و برای مقایسه از عملگر <و>و= استفاده کردم بر اساس کوچک بزرگتری کدای اسکی

ممنون میشم کوئری قابل استفاده ای بهم ارائه بدین .
موفق باشید

hamed_bostan
پنج شنبه 03 آبان 1386, 15:33 عصر
ممنون میشم یکی راهنمایی کنه . بگه هم جایی بد توضیح دادم بگین باز ترش کنم
ممنون

حمیدرضاصادقیان
پنج شنبه 03 آبان 1386, 16:00 عصر
Select Roomcode from Tblroom where roomcode not in(select
roomcode from reserveRoom where date1 between '86/01/01' and '86/02/01')

whitehat
پنج شنبه 03 آبان 1386, 17:20 عصر
این کوئری اتاقهایی را بر می گرداند که در این بازه اصلا رزرو نشده اند.فکر نمی کنم منظور این باشه.
@hamed_bostan: (http://barnamenevis.org/forum/member.php?u=9336) شما نمی توانید این مسئله را با کوئری حل کنید چون نمی توانید از چیزی که در Database نیست کوئری بگیرید! شما در نهایت می توانید کوئری بزنید که اتاقهایی ر ا برگرداند که در تاریخهایی خالی است اما این مشروط به آن است که در آن بازه حداقل یک بار آن تاریخ در جدول شما موجود باشد، اگر تاریخی اصلا وارد نشده بر روی آنرا نمی توانید در جوابهای مشاهده کنید!
برای چیزی که در بالا گفتم این کوئری را امتحان کنید(تست کنید و نتیجه را اعلام کنید)


Select Distinct * from
(
Select RoomID,ReservedDate From ReservedRoom
Where (ReservedDate>=1386/01/01)
And (ReservedDate<=1386/02/01)
Group By ReservedDate,RoomID
) As ResRoomTemp
FULL Outer Join
(
Select RoomID From Room
Where (ReservedDate>=1386/01/01)
And (ReservedDate<=1386/02/01)
) As RoomTemp
On ReservedRoom.RoomID=Room.RoomID
Where ResRoomTemp.ReservedDate Is Null
راه حل دیگه اینه که شما یک SP بنویسید و ماهها را در یک جدول موقت بصورت سطر سطر وارد کنید و با جدول اتاقهای رزرو شده Semi Join کنید
موفق باشید

hamed_bostan
جمعه 04 آبان 1386, 12:40 عصر
دوستان یه چیزی رو مد نظر ندارن و اون اینکه همه جا ما دو تا تاریخ دارم . چه واسه رزرو و چه واسه جستجو ولی دوستان هر دو فقط یه تاریخ رو در نظر میگیرن . البته راه حل اقای صادقیان با کمی تغییر در شرط جستجو تقریبا درست شده البته مطمعن نیستم ولی روش whitehat عزیز هم قشنگ و درست به نظر میاد یه تست کنم نتیجه رو خبر میدم . مشتاقانه منتظر راه حل های دوشتانم که بهترین شیوه رو پیدا کنیم . ممنونم

supporter
شنبه 05 آبان 1386, 22:09 عصر
نگاهی هم به کد زیر بندازید شاید به دردتون خورد:




SELECT * FROM Room R1
WHERE NOT EXISTS ( SELECT * FROM ReservedRoom R2
WHERE R2.RoomID = R1.ID
AND ( (R2.FromDate BETWEEN @FromDate AND @ToDate)
OR (R2.ToDate BETWEEN @FromDate AND @ToDate)
)
)