আমি সাপ্তাহিক ছুটি ব্যতীত দুটি ভিন্ন তারিখের মধ্যে দিনের সংখ্যা পাওয়ার চেষ্টা করছি।
আমি জানি না কীভাবে এই ফলাফলটি অর্জন করা যায়।
আমি সাপ্তাহিক ছুটি ব্যতীত দুটি ভিন্ন তারিখের মধ্যে দিনের সংখ্যা পাওয়ার চেষ্টা করছি।
আমি জানি না কীভাবে এই ফলাফলটি অর্জন করা যায়।
উত্তর:
ধরে নিই যে "সাপ্তাহিক ছুটির দিন" বলতে আপনার অর্থ শনিবার এবং রবিবার , এটি আরও সহজ হতে পারে:
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()
। এসআরএফ (রিটার্নিং ফাংশনগুলি সেট করুন), "টেবিল-ফাংশন" হিসাবেও উল্লেখ করা হয়, FROM
ক্লজের টেবিলের মতো ব্যবহার করা যেতে পারে ।
বিশেষত দ্রষ্টব্য যাতে আউটপুটে উপরের সীমাটি generate_series()
অন্তর্ভুক্ত থাকে , যতক্ষণ না একটি পূর্ণ বিরতি (তৃতীয় প্যারামিটার) ফিট হয়। উপরের সীমানাটি কেবলমাত্র বাদ দেওয়া হয় যদি শেষ ব্যবধানটি কেটে ফেলা হয়, যা পুরো দিনগুলির ক্ষেত্রে হয় না।
এক্সট্রা্যাক্ট () এর প্যাটার্নISODOW
সহ , রবিবার 7
আইএসও মান অনুসারে রিপোর্ট করা হয় are একটি সহজ 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
;
ধরে নিই যে সপ্তাহান্তে শনি ও রবিবার, আপনি নিম্নলিখিত এসকিউএল ব্যবহার করতে পারেন।
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) এর সাথে তারিখগুলি প্রতিস্থাপন করুন।
আপনার কয়েকটি বিষয় খেয়াল করা দরকার: -
আপনি পোস্টগ্রিজএসকিউএল এর কোন সংস্করণটি চালাচ্ছেন তা উল্লেখ করেননি। এটি 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'
আমি আপনাকে যখনই চাইবে ব্যবহারের জন্য একটি ফাংশন তৈরি করতে এবং কম লিখতে পরামর্শ দিই; )
উপরের এই কোডটি একটি বর্গফুট ফাংশন তৈরি করবে যা সাপ্তাহিক ছুটির দিনগুলি (শনি, রৌদ্র) গণনা করে এবং ফেরত দেয়। এই ফাংশনটি ব্যবহার করার জন্য আপনার যেভাবে আরও নমনীয়তা পাবেন Just
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)