मैं सप्ताहांत को छोड़कर, दो अलग-अलग तिथियों के बीच दिनों की संख्या प्राप्त करने की कोशिश कर रहा हूं।
मुझे नहीं पता कि इस परिणाम को कैसे हासिल किया जाए।
मैं सप्ताहांत को छोड़कर, दो अलग-अलग तिथियों के बीच दिनों की संख्या प्राप्त करने की कोशिश कर रहा हूं।
मुझे नहीं पता कि इस परिणाम को कैसे हासिल किया जाए।
जवाबों:
यह मानते हुए कि "सप्ताहांत" से आपका मतलब है शनिवार और रविवार , यह और भी सरल हो सकता है:
SELECT count(*) AS count_days_no_weekend
FROM generate_series(timestamp '2014-01-01'
, timestamp '2014-01-10'
, interval '1 day') the_day
WHERE extract('ISODOW' FROM the_day) < 6;
आपको इसके लिए अतिरिक्त उपश्रेणी स्तर की आवश्यकता नहीं है generate_series()
। SRF (रिटर्निंग फ़ंक्शंस), जिसे "टेबल-फ़ंक्शंस" के रूप में भी जाना जाता है, का उपयोग FROM
क्लॉज़ में टेबल की तरह किया जा सकता है ।
विशेष रूप से ध्यान दें कि आउटपुट में ऊपरी बाउंड generate_series()
शामिल है , जब तक कि एक पूर्ण अंतराल (तीसरा पैरामीटर) फिट बैठता है। ऊपरी सीमा को केवल तभी बाहर रखा जाता है जब अंतिम अंतराल को काट दिया जाएगा, जो पूरे दिनों के मामले में नहीं है।
साथ पैटर्न ISODOW
निकालने () के लिए , रविवार के रूप में रिपोर्ट कर रहे हैं 7
आईएसओ मानक के अनुसार,। एक सरल WHERE
स्थिति के लिए अनुमति देता है ।
बल्कि इनपुट के generate_series()
साथ कॉल करें timestamp
। यहाँ क्यों है:
count(*)
count(the_day)
इस मामले में भी ऐसा करने से थोड़ा कम और तेज़ है ।
निचले और / या ऊपरी बाउंड को बाहर करने के लिए , तदनुसार 1 दिन जोड़ें / घटाएं। आमतौर पर, आप निचले को शामिल कर सकते हैं और ऊपरी सीमा को बाहर कर सकते हैं:
SELECT count(*) AS count_days_no_weekend
FROM generate_series(timestamp '2014-01-01'
, timestamp '2014-01-10' - interval '1 day'
, interval '1 day') the_day
WHERE extract('ISODOW' FROM the_day) < 6;
यह उदाहरण 2013-12-15 और 2014-01-02 (सम्मिलित रूप से) के बीच सभी तिथियों की गणना करता है। दूसरा कॉलम सप्ताह का दिन (संख्यात्मक रूप से, 0 और 6 के बीच) देता है। तीसरे कॉलम में यह चिन्हित किया गया है कि सप्ताह का दिन शनिवार / रविवार है या नहीं (आपको सप्ताहांत में जो विचार करना है उसे अनुकूलित करना होगा) और वह है जो सप्ताह के दिनों की गिनती के लिए इस्तेमाल किया जा सकता है।
select '2013-12-15'::date + i * interval '1 day',
extract('dow' from '2013-12-15'::date + i * interval '1 day') as dow,
case when extract('dow' from '2013-12-15'::date + i * interval '1 day') in (0, 6)
then false
else true end as is_weekday
from generate_series(0, '2014-01-02'::date - '2013-12-15'::date) i
;
यह मानते हुए कि सप्ताहांत शनिवार और रविवार है, आप निम्न SQL का उपयोग कर सकते हैं।
select count(the_day) from
(select generate_series('2014-01-01'::date, '2014-01-10'::date, '1 day') as the_day) days
where extract('dow' from the_day) not in (0,6)
अपनी पसंद से तारीखें बदलें और (0,6) सप्ताह के दिनों के साथ जिन्हें आप बाहर करना चाहते हैं।
ध्यान देने योग्य कुछ बातें: -
आपने उल्लेख नहीं किया है कि आप PostgreSQL का कौन सा संस्करण चला रहे हैं। यह 9.1+ पर काम करता है लेकिन निचले संस्करणों पर काम करना चाहिए।
चुने हुए दिनांक जनरेट_सरीज का उपयोग करते समय समावेशी होते हैं। इसलिए यदि आप बीच में दिन चाहते हैं तो प्रत्येक तिथि में 1 दिन जोड़ें।
वहाँ कुछ चीजें आप इस आसान बनाने के लिए कर सकते हैं। मेरे द्वारा उपयोग की जाने वाली विधि यह सुनिश्चित करने के लिए होगी कि तिथियों की एक तालिका उपलब्ध है। आप जल्दी से एक ऐसा बना सकते हैं:
CREATE TABLE [dbo].[Dates]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY(0,1),
[Date] Date NOT NULL unique,
isWeekend BIT NOT NULL DEFAULT(0)
)
एक बार तालिका बन जाने के बाद, आपको इसे अपेक्षाकृत तेज़ी से तारीख डेटा के साथ आबाद करने में सक्षम होना चाहिए।
set datefirst 6 --start date is saturday
INSERT INTO dbo.Dates(Date, isWeekend)
select
Date,
case datepart(weekday,date)
--relies on DateFirst being set to 6
when 2 then 1
when 1 then 1
else 0
end as isWeekend
from (
select
dateadd(day, number - 1, 0) as date
from (
SELECT top 100000 row_number() over (order by o.object_id) as number
FROM sys.objects o
cross join sys.objects b
cross join sys.objects c
)numbers
)data
फिर आप इस तालिका से रिकॉर्ड की एक त्वरित गणना के रूप में अपनी क्वेरी लिख सकते हैं।
select count(*) as NumberOfWeekDays
from dbo.dates
where isWeekend = 0
and date between '1 Jan 2013' and '31 Dec 2013'
मैं आपको सुझाव देता हूं कि जब भी आप चाहें, उपयोग के लिए एक फ़ंक्शन बनाएं और कम लिखें; )
ऊपर दिया गया यह कोड एक sql फ़ंक्शन बनाएगा जो सप्ताहांत के दिनों (शनि, सूर्य) की मात्रा को गिनता है और वापस करता है। जिस तरह से आपके पास इस फ़ंक्शन का उपयोग करने के लिए अधिक लचीलापन होगा।
CREATE OR REPLACE FUNCTION <YourSchemaNameOptional>.count_full_weekend_days(date, date)
RETURNS bigint AS
$BODY$
select COUNT(MySerie.*) as Qtde
from (select CURRENT_DATE + i as Date, EXTRACT(DOW FROM CURRENT_DATE + i) as DiaDate
from generate_series(date ($1) - CURRENT_DATE, date ($2) - CURRENT_DATE ) i) as MySerie
WHERE MySerie.DiaDate in (6,0);
$BODY$
LANGUAGE 'SQL' IMMUTABLE STRICT;
उसके बाद, आप एक अंतराल में केवल सप्ताहांत के दिनों की संख्या वापस करने के लिए फ़ंक्शन का उपयोग कर सकते हैं । यहाँ का उपयोग करने के लिए उदाहरण है:
SELECT <YourSchemaNameOptional>.count_full_weekend_days('2017-09-11', '2017-09-25') as days; --> RES: 4
इस चयन को चार वापस करना होगा क्योंकि पहला और दूसरा दिन सोमवार हैं, और हमारे बीच 2 शनिवार और 2 रविवार हैं।
अब, केवल व्यावसायिक दिनों (सप्ताहांत के बिना) पर लौटने के लिए , जैसा कि आप चाहते हैं , बस एक घटाव बनाएं, जैसे नीचे दिए गए उदाहरण:
SELECT (date '2017-09-25' - date '2017-09-11' ) - <YourSchemaName>.count_full_weekend_days('2017-09-11', '2017-09-25'); --> RES: 14 - 4 = 10
-- Returns number of weekdays between two dates
SELECT count(*) as "numbers of days”
FROM generate_series(0, (‘from_date’::date - 'todate'::date)) i
WHERE date_part('dow', 'todate'::date + i) NOT IN (0,6)
-- Returns number of weekdays between two dates
SELECT count(*) as days
FROM generate_series(0, ('2014/04/30'::date - '2014/04/01'::date)) i
WHERE date_part('dow', '2014/04/01'::date + i) NOT IN (0,6)