[MSSQL] SQL กับการบวก/ลบวันที่

วันนี้ผมได้งานจากที่่ทำงานมาให้เขียน Query เพื่อแจ้งเตือนสินค้าที่หมดอายุล่วงหน้าตามวันที่กำหนดไว้ ระหว่างวันที่กำหนดจนถึงจำนวนวันที่แจ้งเตือนล่วงหน้า โดยเอาผลัลพธ์ที่ได้มาจัดโปรโมชั่นลดแลกแจกแถมกัน (สมมติว่าเป็น 7 วัน) โดยผมค่อยๆแนะนำไปทีละขั้นตอน ดังนี้

เตรียมข้อมูล

  • กำหนดโครงสร้างตาราง ดังรูป
    โครงสร้างตารางที่ใช้ในบทความนี้
  • ใส่ช้อมูลเตรียมลงไป ดังรูป
    ข้อมูลที่ใช้ในบทความนี้

ลองผิดลองถูก

จากโจทย์มาลองแปลงเป็นแนวคิด "เลือกสินค้าที่มีวันหมดอายุอยู่ในช่วง วันที่ปัจจุบัน จนถึง วันที่ปัจจุบัน + 7 " ถ้าเอามาแปลงเป็น Query ต้องแปลงอย่างไร ใช้อะไรบ้าง ซึ่งใช้ได้หลากหลายแบบ ตอนนี้ผมขอใช้ Between ก่อน ปัญหาถัดมา คือ  วันที่ปัจจุบัน + 7 สามารถเขียน Query ได้อย่างไร เขียนแทนค่าตรงๆ หรือใช้ฟังก์ชั่นช่วย

ปัญหา คือ "2013-11-07"+7  ใช้ได้ หรือไม่ ?

  • ลองเขียน Query ดังนี้
DECLARE @ProcessDate As Date = '2013-11-01'
SELECT Product_ID, Product_Name, Unit, PricePerUnit, ExpireDate
FROM PRODUCT
WHERE ExpireDate BETWEEN @ProcessDate AND @ProcessDate + 7
  • ลองรันดูพบว่าใช้ไม่ได้ เกิด Error Message ซึ่งสาเหตุของ Error เกิดจากตัวแปร Process Date มีชนิดข้อมูล Date ซึ่งไม่สามารถนำมาบวกกับ 7 ซึ่งมีชนิดข้อมูล Integer ได้

เพิ่มเติม: หากกำหนดชนิดข้อมูลแบบ Datetime ตัว SQL Server ยอมให้ ลบกับข้อมูลประเภท Integer ได้

ลองทำฟังก์ชัน DATEADD ซึ่งมีหน้าที่จัดการบวก/ลบวันที่

รูปแบบการใช้งาน ดังนี้

DATEADD (datepart , number , date )
  • datepart คือ รูปแบบของเวลา เช่น ชั่วโมง(DAY), สัปดาห์(WEEK) หรือ ไตรมาส(QUARTER) เป็นต้น
  • number คือ จำนวนเวลาที่ต้องการเพิ่ม หรือ ลบ ออก จากโจทย์ เราต้องแจ้งเตือนล่วงหน้า 7 วัน ดังนั้น number เท่ากับ 7
  • date คือ วันตั้งต้น จากโจทย์ คือ ProcessDate น้ันเอง

ลองเขียน Query โดยใช้ DateADD ดังนี้

DECLARE @ProcessDate As Date = '2013-11-01'
SELECT Product_ID, Product_Name, Unit, PricePerUnit, ExpireDate
FROM PRODUCT
WHERE ExpireDate BETWEEN @ProcessDate AND DATEADD(DAY, 7, @ProcessDate)

เมื่อลองรัน Query พบว่าแสดงข้อมูลได้ผลลัพธ์ตรงตามต้องการ ดังรูป

ตัวอย่างอื่นๆที่ใช้ DATEADD โดยกำหนดค่า ProcessDate ดังนี้

DECLARE @ProcessDate As Datetime = '2013-04-23 13:05:07.256'
รูปแบบเวลารูปแบบเวลา
(ตัวย่อ)
Queryผลลัพธ์
MILLISECONDmsSELECT DATEADD(MILLISECOND,1500,@ProcessDate)2013-04-23 13:05:08.757
MINUTEmi, nSELECT DATEADD(MINUTE,15,@ProcessDate)2013-04-23 13:20:07.257
HOURhhSELECT DATEADD(HOUR,-3,@ProcessDate)2013-04-23 10:05:07.257
WEEKDAYdw, wSELECT DATEADD(WEEKDAY,-2,@ProcessDate)2013-04-21 13:05:07.257
WEEKwk, wwSELECT DATEADD(WEEK,4,@ProcessDate)2013-05-21 13:05:07.257
DAYdd, dSELECT DATEADD(DD,4,@ProcessDate)2013-04-27 13:05:07.257
MONTHmm, mSELECT DATEADD(MM,-4,@ProcessDate)2012-12-23 13:05:07.257
QUARTERqq, qSELECT DATEADD(Q,-2,@ProcessDate)2012-10-23 13:05:07.257
YEARyy, yyyySELECT DATEADD(YYYY,-5,@ProcessDate)2008-04-23 13:05:07.257

สรุปผล

จากโจทย์นี้สามารถเขียน Query ได้หลายแบบมากๆ โดยตัวอย่างที่ผมเขียนเป็นการสอนการใช้ฟังก์ชั่น DATEADD ซึ่งสรรพคุณของฟังก์ชั่นนี้สามารถลดจำนวน Code ที่ผู้อ่านเขียนได้แน่นอน และช่วยให้การทำงานของโปรแกรมของเรามีประสิทธิภาพมากยิ่งขึ้นด้วย

แหล่งอ้างอิง


Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts sent to your email.