SQL เชคเวลา

เริ่มโดย @@@, 21 พฤษภาคม 2013, 15:01:31

หัวข้อก่อนหน้า - หัวข้อถัดไป

0 สมาชิก และ 1 ผู้มาเยือน กำลังดูหัวข้อนี้

@@@

คำถามครับ

ต้องการใช้คำสัง SQL เลือกข้อมูลดูห้องว่าง ระหว่างวันที่ 2/05/2103 ถึง   4/05/2103

โดยที่ Table เก็บวัน checkinและcheckout เป็นคนละฟิว

ตาราสมมตินะครับ






ห้องcheckincheckout
A12103-05-012103-05-05
A22103-05-042103-05-08
A32103-05-052103-05-07

จะ เขียนคำสั่ง sql แบบไหนดีครับ
   
รับซื้อเว็บ 100uip ต่อวันขึ้นไป [direct=http://www.rommit.com/forex]EA Forex[/direct]

adidog

ลองศึกษาคำสั่ง between ดูครับ
Certain Dri [direct=http://www.ishiclub.com/]Certain Dri[/direct]
คุณแม่มือใหม่ [direct=http://www.mamyget.com/]คุณแม่มือใหม่[/direct]

vanavat

[direct=http://www.sesonshopping.com]รองเท้าผ้าใบผู้หญิง [/direct][direct=http://www.9manup.com]เสื้อแฟชั่นผู้ชาย[/direct][direct=http://www.sesonshopping.com]รองเท้าเกาหลี[/direct][direct=http://www.sesonshopping.com]รองเท้าผ้าใบผู้หญิง[/direct]

@@@

ถ้าเป็น วันที่ใน ฟิวเดียวกันไม่อยากครับ

แต่นี้มันคนละฟิวครับ
รับซื้อเว็บ 100uip ต่อวันขึ้นไป [direct=http://www.rommit.com/forex]EA Forex[/direct]

Railway

อยู่ที่ว่าเก็บข้อมูลเป็น DATE รึป่าว หรือเก็บเป็น Varchar เฉยๆ ถ้าเก็บเป็น DATE ก็เทียบเหมือนตัวเลขแหละครับ

ouidesignweb

SELECT * FROM ชื่อตาราง WHERE (checkin BETWEEN 2/05/2103 AND 4/05/2103) AND  (checkout BETWEEN 2/05/2103 AND 4/05/2103)

เดาล้วนๆ  :wanwan004: :wanwan004: :wanwan004:

@@@

อ้างถึงจาก: ouidesignweb ใน 21 พฤษภาคม 2013, 16:45:07
SELECT * FROM ชื่อตาราง WHERE (checkin BETWEEN 2/05/2103 AND 4/05/2103) AND  (checkout BETWEEN 2/05/2103 AND 4/05/2103)

เดาล้วนๆ  :wanwan004: :wanwan004: :wanwan004:

แบบนี้ไม่ได้ครับ

เพราะ ถ้าวัน checkin เป็น 01/05/2103 และ checkout เป็น 6/05/2103

จะได้คำตอบว่าไม่มีข้อมูลซึ่งแปลว่าห้องว่าง แต่จริงๆแล้วถูกจองเต็มแล้วครับ

ขอบคุณที่มาตอบครับ
รับซื้อเว็บ 100uip ต่อวันขึ้นไป [direct=http://www.rommit.com/forex]EA Forex[/direct]

normalblue

ปัญหาของคำตอบคือต้องคิด Scenario ของเหตุการณ์ที่จะเกิดขึ้นให้ครบ โดยที่ หากช่วงเวลาระหว่าง Check-in -> Check-out มันไปซ้อนทับกับข้อมูลระยะเวลาในตารางต้อง Mark ไว้ว่า Reserved/Booked

ซึ่งกรณีที่จะเกิดการซ้อนทับ(Booked/Reserved) ก็มี Scenario ดังนี้ครับ
สมุมติ Checking in/out คือเวลาที่ใช้ค้นหา Checked in/out คือที่อยู่ในฐานข้อมูล
1. Checking In >= Checked In and Checking out <= Checked out // ช่วงเวลาที่กำลังค้นหา อยู่ภายในช่วงเวลาที่ห้องถูกจองไปแล้ว
2. Checking In <= Checked In and Checking out >= Checked out // ช่วงเวลาที่กำลังค้นหา ยาวครอบคลุมช่วงเวลาที่ห้องถูกจองไปแล้ว
1. Checking Out >= Checked In and Checking out <= Checked out // ช่วงเวลาที่กำลังค้นหา มีบางส่วนคาบเกี่ยวกับช่วงเวลาที่ห้องถูกจองไปแล้ว

พอกำหนด Scenario ครบก็เอามาเขียนเป็น SQL Statement ครับ

SELECT *
FROM [ROOM_TABLE]
WHERE roomId NOT IN
  (SELECT roomId
   FROM [RESERVATION_TABLE]
   WHERE
       (checkin <= '$checking_in' AND checkout >= '$checking_in') OR
       (checkin >= '$checking_in' AND checkout <= '$checking_out') OR
       (checkin <= '$checking_out' AND checkout >= '$checking_out'))

MapTwoZa

** start/stop คือ ช่วงวันที่ต้องการตรวจสอบ
เทียบ checkin กับ start/stop
จะแบ่งเวลาได้เป็น 3 ช่วง
1. checkin < start
2. checkin between start and stop
3. checkin > stop ตัดข้อนี้ทิ้งได้เลย ยังไงก็ไม่เข้าเงื่อนไข

ทีนี้ก็จะเหลือ 2 เงื่อนไขบน แต่ต้องเพิ่มเงื่อนไขเข้าไปนิดหน่อยให้มันเข้าครับ

1. checkin < start and chckout >= start
2. checkin between start and stop


เอา 2 เงื่อนไขข้างบนนี่ไปเขียนเป็น sql ก็ออกละครับ
Good code quality Developer :D

@@@

#9
ขอบคุณทุกท่านมากครับ +1 ทุกคน

เพิ่มเติม ถ้าใช้วิธีนี้จะได้เหมือนกันมั้ยครับ

SELECT * FROM TABLE   WHERE(begin_date <= '2103-05-07' AND end_date >= '2103-05-05')
รับซื้อเว็บ 100uip ต่อวันขึ้นไป [direct=http://www.rommit.com/forex]EA Forex[/direct]

MapTwoZa

select *
from table
where
(begin_date< date('2103-05-05') and end_date  >= date('2103-05-05'))
or
(begin_date between date('2103-05-05') and date('2103-05-07'))
Good code quality Developer :D

seowizard

ซับซ้อนมาก บองต่ง ห้องว่างที่ว่า คือ checkin checkout ต้องเป็นค่าว่างใช่ไหม แล้วเราจะเอาฟิลด์ date จากไหนมาเช็คช่วงเวลาละทีนี้ อิอิ  :wanwan012:


MapTwoZa

โอ้ว พอคิดดีๆ รายละเอียดเยอะแฮะ

เช่น begin_date = 2103-05-05 แต่ end_date  = null แสดงว่ากำลังอยู่ก็ต้องเอามาคิดด้วย

ก็ต้องเอามาคิดด้วย
อืมมม ก็ต้องแก้ select นิดนึง

select
if(isnull(begin_date),date(0), date(begin_date)) as new_begin_date,
if(isnull(end_date) and isnull(begin_date), date(0), if(isnull(end_date),curdate(), date(end_date))) as new_end_date,
*
from table
where
(new_begin_date< date('2103-05-05') and new_end_date  >= date('2103-05-05'))
or
(new_begin_date between date('2103-05-05') and date('2103-05-07'))
Good code quality Developer :D

seowizard

ถ้าโจทย์มีแค่ 3 ฟิลด์  เอาง่าย ๆเลยก็คิดหาเฉพาะวันที่ checkout ในช่วงเวลาดังกล่าวครับ นั่นหมายถึงช่วงเวลานั้นจะมีการ checkout ซึ่งแน่นอนมันจะว่าง

SELECT room FROM table WHERE checkout BETWEEN 2013-05-02 AND 2013-05-04

MapTwoZa

อ้างถึงจาก: seowizard ใน 22 พฤษภาคม 2013, 16:47:13
ถ้าโจทย์มีแค่ 3 ฟิลด์  เอาง่าย ๆเลยก็คิดหาเฉพาะวันที่ checkout ในช่วงเวลาดังกล่าวครับ นั่นหมายถึงช่วงเวลานั้นจะมีการ checkout ซึ่งแน่นอนมันจะว่าง

SELECT room FROM table WHERE checkout BETWEEN 2013-05-02 AND 2013-05-04

ไม่ได้ครับ ถ้า checkin วันที่ 1 แล้ว checkout วันที่ 5 ล่ะ
แล้วถ้า chcking วันที่ 1 แล้ว checkout null ละ
Good code quality Developer :D

seowizard

อ้างถึงจาก: MapTwoZa ใน 22 พฤษภาคม 2013, 16:53:31
อ้างถึงจาก: seowizard ใน 22 พฤษภาคม 2013, 16:47:13
ถ้าโจทย์มีแค่ 3 ฟิลด์  เอาง่าย ๆเลยก็คิดหาเฉพาะวันที่ checkout ในช่วงเวลาดังกล่าวครับ นั่นหมายถึงช่วงเวลานั้นจะมีการ checkout ซึ่งแน่นอนมันจะว่าง

SELECT room FROM table WHERE checkout BETWEEN 2013-05-02 AND 2013-05-04

ไม่ได้ครับ ถ้า checkin วันที่ 1 แล้ว checkout วันที่ 5 ล่ะ
แล้วถ้า chcking วันที่ 1 แล้ว checkout null ละ

โจทย์เขาต้องการหาห้องว่างในช่วงเวลาดังกล่าว มันไม่มีตัวบ่งชี้ว่าอะไรที่บอกว่าห้องนั้นว่าง นอกจากเวลา check out  ครับ
(ถ้า checkin วันที่ 1 แล้ว checkout วันที่ 5 ก็ไม่อยู่ในเงื่อนไขครับ แสดงว่าห้องนั้นไม่ว่าง
ถ้ามี checkin แต่ checkout เป็น null ก็แสดงว่าห้องนั้นจองอยู่ หรือเป็น null ทั้งคู่ห้องนั้นก็คือห้องว่าง แต่มันอยู่ช่วงเวลาไหน)
เงื่อนไขที่เราสนใจคือ checkout ที่อยู่ระหว่างวันที่ 2-4  ให้แสดง room นั้นออกมา(อาจจะมี room ที่ยังไม่ว่างเสียทีเดียว เนื่องจากช่วงเวลาทาบเกี่ยวกันอยู่)
มันอาจจะไม่ตรงกับความต้องการเท่าไร แต่ถ้าโครงสร้างของ table มีฟิลด์ประมาณนี้คงต้องใช้วิธีนี้ละครับ   :P

@@@

เหมือนจะง่ายๆแต่คิดอยากเหมือนกันครับ
รับซื้อเว็บ 100uip ต่อวันขึ้นไป [direct=http://www.rommit.com/forex]EA Forex[/direct]

seowizard

ถ้าเป็นโปรแกรมที่เขียนขึ้นเองลอง Optimize Database ใหม่ครับ  ทำ Normalization เขียน ER ดี ๆ จะทำให้การ Query ง่ายขึ้น

MapTwoZa

#19


#ไม่ว่าง

select
if(isnull(begin_date),date(0), date(begin_date)) as new_begin_date,
if(isnull(end_date) and isnull(begin_date), date(0), if(isnull(end_date),curdate(), date(end_date))) as new_end_date,
*
from table
where
(new_begin_date< date('2103-05-05') and new_end_date  >= date('2103-05-05'))
or
(new_begin_date between date('2103-05-05') and date('2103-05-07'))


#ว่าง

select
if(isnull(begin_date),date(0), date(begin_date)) as new_begin_date,
if(isnull(end_date) and isnull(begin_date), date(0), if(isnull(end_date),curdate(), date(end_date))) as new_end_date,
*
from table
where
not (new_begin_date< date('2103-05-05') and new_end_date  >= date('2103-05-05'))
and
not (new_begin_date between date('2103-05-05') and date('2103-05-07'))
Good code quality Developer :D

normalblue

อ้างถึงจาก: seowizard ใน 22 พฤษภาคม 2013, 17:14:33
โจทย์เขาต้องการหาห้องว่างในช่วงเวลาดังกล่าว มันไม่มีตัวบ่งชี้ว่าอะไรที่บอกว่าห้องนั้นว่าง นอกจากเวลา check out  ครับ
(ถ้า checkin วันที่ 1 แล้ว checkout วันที่ 5 ก็ไม่อยู่ในเงื่อนไขครับ แสดงว่าห้องนั้นไม่ว่าง
ถ้ามี checkin แต่ checkout เป็น null ก็แสดงว่าห้องนั้นจองอยู่ หรือเป็น null ทั้งคู่ห้องนั้นก็คือห้องว่าง แต่มันอยู่ช่วงเวลาไหน)
เงื่อนไขที่เราสนใจคือ checkout ที่อยู่ระหว่างวันที่ 2-4  ให้แสดง room นั้นออกมา(อาจจะมี room ที่ยังไม่ว่างเสียทีเดียว เนื่องจากช่วงเวลาทาบเกี่ยวกันอยู่)
มันอาจจะไม่ตรงกับความต้องการเท่าไร แต่ถ้าโครงสร้างของ table มีฟิลด์ประมาณนี้คงต้องใช้วิธีนี้ละครับ   :P

มันจะไม่มีประโยชน์เลยสำหรับข้อมูลชุดอื่นครับ... เวลาเราเขียน SQL Command ต้องพึงนึกถึงคำว่า Robust ไว้จนชินครับ เพราะหากมัน Robust แล้ว มัน Reusable ด้วย
ใช้ได้กับทุก Possibility ของข้อมูล

ถ้าหากคุณคิดว่า Constraint ของคุณกำหนดด้วย PHP ได้ไม่ขาดตกบกพร่อง ไม่ได้ปล่อยค่าว่างเข้ามา Search ใช้ของคุณ MapTwoZa ด้านบนครับ
ถ้าหากคุณคิดจะป้องกันตั้งแต่ PHP มา Database ก็เสริมอีกชั้น ก็กำหนดให้ครอบคลุมอีกรอบดักจับหากค่าใดค่าหนึ่งว่าง ใช้ของผมข้างบนครับ

ผมไม่เชื่อว่านอกจากตาราง Booking/Reservation แล้ว จะไม่มีตาราง Room หากไม่มีจริงๆ ก็เพิ่มเถอะครับ หากไม่อยากปวดหัวในอนาคต

สุดท้าย ต้องบอกว่าการออกแบบระบบจอง ค่อนข้างง่าย เมื่อเที่ยบกับ Logic ในแขนงอื่นๆ ครับ เช่น SCM, CRM เป็นต้น ออกแบบมาดี ตอนเทสก็ไม่ลำบากมาก ทำไปเรื่อยๆ เดี๋ยวมันก็ชินเองครับ

seowizard

อ้างถึงจาก: normalblue ใน 22 พฤษภาคม 2013, 19:07:44
อ้างถึงจาก: seowizard ใน 22 พฤษภาคม 2013, 17:14:33
โจทย์เขาต้องการหาห้องว่างในช่วงเวลาดังกล่าว มันไม่มีตัวบ่งชี้ว่าอะไรที่บอกว่าห้องนั้นว่าง นอกจากเวลา check out  ครับ
(ถ้า checkin วันที่ 1 แล้ว checkout วันที่ 5 ก็ไม่อยู่ในเงื่อนไขครับ แสดงว่าห้องนั้นไม่ว่าง
ถ้ามี checkin แต่ checkout เป็น null ก็แสดงว่าห้องนั้นจองอยู่ หรือเป็น null ทั้งคู่ห้องนั้นก็คือห้องว่าง แต่มันอยู่ช่วงเวลาไหน)
เงื่อนไขที่เราสนใจคือ checkout ที่อยู่ระหว่างวันที่ 2-4  ให้แสดง room นั้นออกมา(อาจจะมี room ที่ยังไม่ว่างเสียทีเดียว เนื่องจากช่วงเวลาทาบเกี่ยวกันอยู่)
มันอาจจะไม่ตรงกับความต้องการเท่าไร แต่ถ้าโครงสร้างของ table มีฟิลด์ประมาณนี้คงต้องใช้วิธีนี้ละครับ   :P

มันจะไม่มีประโยชน์เลยสำหรับข้อมูลชุดอื่นครับ... เวลาเราเขียน SQL Command ต้องพึงนึกถึงคำว่า Robust ไว้จนชินครับ เพราะหากมัน Robust แล้ว มัน Reusable ด้วย
ใช้ได้กับทุก Possibility ของข้อมูล

ถ้าหากคุณคิดว่า Constraint ของคุณกำหนดด้วย PHP ได้ไม่ขาดตกบกพร่อง ไม่ได้ปล่อยค่าว่างเข้ามา Search ใช้ของคุณ MapTwoZa ด้านบนครับ
ถ้าหากคุณคิดจะป้องกันตั้งแต่ PHP มา Database ก็เสริมอีกชั้น ก็กำหนดให้ครอบคลุมอีกรอบดักจับหากค่าใดค่าหนึ่งว่าง ใช้ของผมข้างบนครับ

ผมไม่เชื่อว่านอกจากตาราง Booking/Reservation แล้ว จะไม่มีตาราง Room หากไม่มีจริงๆ ก็เพิ่มเถอะครับ หากไม่อยากปวดหัวในอนาคต

สุดท้าย ต้องบอกว่าการออกแบบระบบจอง ค่อนข้างง่าย เมื่อเที่ยบกับ Logic ในแขนงอื่นๆ ครับ เช่น SCM, CRM เป็นต้น ออกแบบมาดี ตอนเทสก็ไม่ลำบากมาก ทำไปเรื่อยๆ เดี๋ยวมันก็ชินเองครับ

ครับ  ผมวิเคราะห์แบบบ้าน ๆ อย่าถือสาเลย อิอิ  :wanwan012:

normalblue

อ้างถึงจาก: seowizard ใน 22 พฤษภาคม 2013, 19:35:57
ครับ  ผมวิเคราะห์แบบบ้าน ๆ อย่าถือสาเลย อิอิ  :wanwan012:

ครับ ช่วยๆ กันตอบ Braistorm กัน ความคิดเห็นจะได้หลากหลาย คนฟังจะได้ดูมีทางเลือก บ้านก็อบอุ่นครับ  :wanwan019:

p44n

พวกท่านทำไมคิดกัน ให้ยุ่งยากขนาดนั้นคับ ไม่ปวดหัวเหรอ  :wanwan044:
Python, PHP OOP, MVC CodeIgniter, MongoDB, MySQL, MsSQL ,CSS Tableless, Responsive Design, Cross-platform, Javascript, jQuery, AngularJS, NodeJS,  Fackbook API, Paypal API, Omise API, Google Map API, C# Window Applications, .NET Framework, JAVA (Android Developer, JSP), Hybrid Application with Cordova + Ionic Framework, ReactJS, React Native