รบกวนถามว่า ถ้าผมมี field รับค่าวันที่ 2 field ( form 6i ) คือ start_date และ end_date พอรับค่าเข้าไปเช่น
start_date = 01/01/2551
end_date = 31/01/2551
ผมอยากทราบว่า 1..มีวันที่เป็นวันทำงาน คือ จันทร์ ถึง ศุกร์ กี่วัน
2..วันหยุด คือ เสาร์ และ อาทิตย์ กี่วัน
ในช่วง start_date ถึง end_date
condition มีเพียงเท่านี้ครับ ไม่ทราบว่าท่านใดพอมีแนวทาง หรือตัวอย่าง บ้างครับ
ขอบคุณมากครับ
Page 1 of 1
นับวันทำงาน และ วันหยุด
#2
Posted 04 December 2009 - 10:18 AM
SELECT COUNT(DAY) FROM (
SELECT TO_CHAR(TO_DATE('01/12/2009','dd/mm/yyyy') + (LEVEL-1),'day') DAY
FROM dual CONNECT BY LEVEL <= SUBSTR(LAST_DAY(TO_DATE('01/12/2009','dd/mm/yyyy')),1,2)
)
WHERE trim(DAY) IN('saturday','sunday')
อันนี้ คิดในหนึ่งเดือนอ่ะครับ count วันเสาร์กับวันอาทิตย์ครับค่อยเอาไปลบกับจำนวนวันจริงเอาครับ
ถ้ามากกว่านั้นก็เอาวันที่มาลบกันแล้วเอาไปใส่แทนตรง SUBSTR(LAST_DAY(TO_DATE('01/12/2009','dd/mm/yyyy')),1,2)
ส่วนโค้ดผมอะแดปมาจากของพี่ siamnobita จากกระทู้ที่ถามเรื่องเวลาไรนี้ล่ะครับ
ผมก็ไม่ค่อยรู้เรื่องเหมือนกันครับ ฮ่าๆ
รอท่านอื่นมาต่อครับ
ปล. oracle 10g คับ
SELECT TO_CHAR(TO_DATE('01/12/2009','dd/mm/yyyy') + (LEVEL-1),'day') DAY
FROM dual CONNECT BY LEVEL <= SUBSTR(LAST_DAY(TO_DATE('01/12/2009','dd/mm/yyyy')),1,2)
)
WHERE trim(DAY) IN('saturday','sunday')
อันนี้ คิดในหนึ่งเดือนอ่ะครับ count วันเสาร์กับวันอาทิตย์ครับค่อยเอาไปลบกับจำนวนวันจริงเอาครับ
ถ้ามากกว่านั้นก็เอาวันที่มาลบกันแล้วเอาไปใส่แทนตรง SUBSTR(LAST_DAY(TO_DATE('01/12/2009','dd/mm/yyyy')),1,2)
ส่วนโค้ดผมอะแดปมาจากของพี่ siamnobita จากกระทู้ที่ถามเรื่องเวลาไรนี้ล่ะครับ
ผมก็ไม่ค่อยรู้เรื่องเหมือนกันครับ ฮ่าๆ
SELECT TO_CHAR( TRUNC ( SYSDATE) + (LEVEL-1)/24/60,'HH24.MI') FROM dual CONNECT BY LEVEL <= 24*60
รอท่านอื่นมาต่อครับ
ปล. oracle 10g คับ
#3
Posted 04 December 2009 - 11:53 AM
ได้แล้วครับ
และขอบคุณ คุณ JoeIMIsu ด้วยครับ
สร้างเป็น function ไว้นะครับ
ลอง query ดู select daysbetween('01/01/2552','11/01/2552') from dual;
สร้างเป็น function ไว้นะครับ
CREATE OR REPLACE FUNCTION daysbetween (dateFrom in date, dateTo in date) return number IS begin declare days number; begin days := dateTo-dateFrom+1; for i in 0 .. days-1 loop -- In my locale, the week starts Sun so Sun = 1, Sat = 7 if to_char(dateFrom+i, 'd') in (1, 7) then days := days - 1; end if; end loop; return days; end; end;
ลอง query ดู select daysbetween('01/01/2552','11/01/2552') from dual;
#4
Posted 21 December 2009 - 04:36 PM
SELECT COUNT (*)
FROM (SELECT TO_CHAR (calendars.days,
'D',
'nls_date_language=american'
) abbrv,
DECODE (TO_CHAR (calendars.days,
'D',
'nls_date_language=american'
),
'1', 'W',
'7', 'W',
'B'
) dow,
days
FROM (SELECT TRUNC
(ADD_MONTHS
(LAST_DAY
(fnd_date.canonical_to_date
(:start_date)
),
-1
)
)
+ LEVEL days
FROM DUAL
CONNECT BY LEVEL <=
( TRUNC
(LAST_DAY
(fnd_date.canonical_to_date
(:end_date)
)
)
- TRUNC
(fnd_date.canonical_to_date (:start_date),
'MONTH'
)
)
+ 1) calendars) calen1
WHERE calen1.dow = 'W'concept เดียวกันกับ function ครับ แต่เขียนเป็น SQL
#5
Posted 29 December 2009 - 10:38 AM
ลองคิดเล่น ๆ ว่าถ้าใช้ built-in function ล้วน ๆ จะทำได้ไหม ผลออกมาอย่างที่เห็นครับ
หลักการคือ หาวันเสาร์แรก และ เสาร์สุดท้ายในช่วงมาโดยใช้ฟังก์ชั่น next_day(d1,7) และ next_day(d2,7)-7
นับ weekend ช่วงที่หนึ่งคือ ตั้งแต่วันแรกจนถึงวันเสาร์แรก จะมีเสาร์อาทิตย์เท่ากับจำนวนวันที่เกิน 5 วัน
นับ weekend ช่วงที่สองคือ ตั้งแต่วันเสาร์แรกจนถึงวันเสาร์สุดท้าย จะมีเสาร์อาทิตย์เท่ากับจำนวนวันหารเจ็ดคูณสอง
นับ weekend ช่วงที่สามคือ ตั้งแต่วันเสาร์สุดท้ายจนถึงวันสุดท้าย จะมีเสาร์อาทิตย์เท่ากับจำนวนวัน แต่ไม่เกินสอง
จริง ๆ logic นี้ อาจมีจุดอ่อนในกรณีที่ ช่วงวันที่ยาวไม่พอที่จะแบ่งเป็นสามช่วงได้ แต่เท่าที่ทดสอบดูหลาย ๆ เคส
พบว่าจำนวนวันจากช่วงที่สองจะติดลบ และชดเชยกันจนได้ผลลัพธ์ที่ถูกต้องอยู่ดี ถ้าใครลองทดสอบดูแล้วเจอเคส
ที่ใช้ไม่ได้ รบกวนแจ้งด้วยนะครับ ขอบคุณครับ
SQL> select d1, d2 2 , greatest((next_day(d1,7)-d1)-5,0) 3 + ((next_day(d2,7)-7)-next_day(d1,7))/7*2 4 + least ((d2+1) - (next_day(d2,7)-7),2) 5 as cnt 6 from weekend_count 7 / D1 D2 CNT ------------------- ------------------- ---------- 01/12/2009 00:00:00 31/12/2009 00:00:00 8 05/12/2009 00:00:00 05/12/2009 00:00:00 1 05/12/2009 00:00:00 06/12/2009 00:00:00 2 05/12/2009 00:00:00 12/12/2009 00:00:00 3 07/12/2009 00:00:00 11/12/2009 00:00:00 0 01/01/2010 00:00:00 31/01/2010 00:00:00 10 6 rows selected.
หลักการคือ หาวันเสาร์แรก และ เสาร์สุดท้ายในช่วงมาโดยใช้ฟังก์ชั่น next_day(d1,7) และ next_day(d2,7)-7
นับ weekend ช่วงที่หนึ่งคือ ตั้งแต่วันแรกจนถึงวันเสาร์แรก จะมีเสาร์อาทิตย์เท่ากับจำนวนวันที่เกิน 5 วัน
นับ weekend ช่วงที่สองคือ ตั้งแต่วันเสาร์แรกจนถึงวันเสาร์สุดท้าย จะมีเสาร์อาทิตย์เท่ากับจำนวนวันหารเจ็ดคูณสอง
นับ weekend ช่วงที่สามคือ ตั้งแต่วันเสาร์สุดท้ายจนถึงวันสุดท้าย จะมีเสาร์อาทิตย์เท่ากับจำนวนวัน แต่ไม่เกินสอง
จริง ๆ logic นี้ อาจมีจุดอ่อนในกรณีที่ ช่วงวันที่ยาวไม่พอที่จะแบ่งเป็นสามช่วงได้ แต่เท่าที่ทดสอบดูหลาย ๆ เคส
พบว่าจำนวนวันจากช่วงที่สองจะติดลบ และชดเชยกันจนได้ผลลัพธ์ที่ถูกต้องอยู่ดี ถ้าใครลองทดสอบดูแล้วเจอเคส
ที่ใช้ไม่ได้ รบกวนแจ้งด้วยนะครับ ขอบคุณครับ
This post has been edited by siamnobi: 29 December 2009 - 10:43 AM
#6
Posted 04 January 2010 - 02:07 PM
เยี่ยมเลยครับ นี่ขนาดนั่งคิดเล่นๆนะเนี่ยะ
This post has been edited by ekkapong: 08 January 2010 - 01:30 PM
Share this topic:
Page 1 of 1

Help











