गैर-व्यावसायिक घंटों को छिपाने के लिए आप Generate_series() फ़ंक्शन का उपयोग कर सकते हैं:
with gaps as (
select
upper(during) as start,
lead(lower(during),1,upper(during)) over (ORDER BY during) - upper(during) as gap
from (
select during
from reservation
union all
select
unnest(case
when pyha is not null then array[tsrange(d, d + interval '1 day')]
when date_part('dow', d) in (0, 6) then array[tsrange(d, d + interval '1 day')]
when d::date = '2012-11-14' then array[tsrange(d, d + interval '9 hours'), tsrange(d + interval '18 hours', d + interval '1 day')]
else array[tsrange(d, d + interval '8 hours'), tsrange(d + interval '18 hours', d + interval '1 day')]
end)
from generate_series(
'2012-11-14'::timestamp without time zone,
'2012-11-14'::timestamp without time zone + interval '2 week',
interval '1 day'
) as s(d)
left join pyha on pyha = d::date
) as x
)
select *
from gaps
where gap > '0'::interval
order by start
मुझे कुछ मुश्किल भागों के बारे में बताएं:
- आपको शनि/सूर्य की तिथियां
pyha
. में डालने की आवश्यकता नहीं है तालिका क्योंकि आप उपयोग कर सकते हैंdate_part('dow', d)
समारोह।pyha
का प्रयोग करें केवल सार्वजनिक अवकाश के लिए तालिका। 'डॉव' क्रमशः सूर्य या शनि के लिए 0 या 6 देता है। - सार्वजनिक अवकाश और शनि/सूर्य को एकल अंतराल (..24) के रूप में दर्शाया जा सकता है। सप्ताह के दिनों को दो अंतरालों (0..8) और (18..24) द्वारा दर्शाया जाना चाहिए, इसलिए unnest() और array[]
- आप generate_series() फ़ंक्शन में प्रारंभ दिनांक और लंबाई निर्दिष्ट कर सकते हैं
प्रश्न के आपके अपडेट के आधार पर मैंने एक और when
जोड़ा है case
. के लिए :
when d::date = '2012-11-14' then array[tsrange(d, d + interval '9 hours'), tsrange(d + interval '18 hours', d + interval '1 day')]
विचार प्रारंभ तिथि के लिए अलग-अलग अंतराल (ओं) का उत्पादन करना है (d::date = '2012-11-14'
):(0..9) और (18..24)