তারিখের সীমাগুলির তুলনা করা


116

মাইএসকিউএলে, যদি আমার কাছে তারিখের ব্যাপ্তিগুলির একটি তালিকা থাকে (রেঞ্জ-স্টার্ট এবং রেঞ্জ-এন্ড)। যেমন

10/06/1983 to 14/06/1983
15/07/1983 to 16/07/1983
18/07/1983 to 18/07/1983

এবং আমি যাচাই করতে চাই যে অন্য তারিখের সীমাতে ইতিমধ্যে তালিকায় রয়েছে এমন কোনও রেঞ্জ রয়েছে, আমি কীভাবে এটি করব?

যেমন

06/06/1983 to 18/06/1983 = IN LIST
10/06/1983 to 11/06/1983 = IN LIST
14/07/1983 to 14/07/1983 = NOT IN LIST

উত্তর:


439

এটি একটি ধ্রুপদী সমস্যা, এবং আপনি যুক্তিটি বিপরীত করা আসলে এটি আরও সহজ easier

আমাকে যদি আপনি একটি উদাহরণ দিতে।

আমি এখানে সময়ের একটি সময় পোস্ট করব এবং অন্যান্য সময়কালের সমস্ত ভিন্নতা যা কোনওভাবে ওভারল্যাপ করে।

           |-------------------|          compare to this one
               |---------|                contained within
           |----------|                   contained within, equal start
                   |-----------|          contained within, equal end
           |-------------------|          contained within, equal start+end
     |------------|                       not fully contained, overlaps start
                   |---------------|      not fully contained, overlaps end
     |-------------------------|          overlaps start, bigger
           |-----------------------|      overlaps end, bigger
     |------------------------------|     overlaps entire period

অন্যদিকে, আমাকে যে সমস্ত ওভারল্যাপ হয় না তাদের সমস্ত পোস্ট করুন:

           |-------------------|          compare to this one
     |---|                                ends before
                                 |---|    starts after

সুতরাং আপনি যদি তুলনাটি সহজ করেন তবে:

starts after end
ends before start

তারপরে আপনি এমন সমস্তগুলি খুঁজে পাবেন যা ওভারল্যাপ হয় না এবং তারপরে আপনি সমস্ত অ-মিলের সময়সীমা খুঁজে পাবেন।

আপনার চূড়ান্ত নয় তালিকার উদাহরণের জন্য, আপনি দেখতে পাচ্ছেন যে এটি দুটি নিয়মের সাথে মেলে।

নিম্নলিখিত সময়সীমার মধ্যে আপনার সীমার বাইরে বা বাইরে থাকা আপনার সিদ্ধান্ত নিতে হবে:

           |-------------|
   |-------|                       equal end with start of comparison period
                         |-----|   equal start with end of comparison period

যদি আপনার টেবিলটিতে রেঞ্জ_এন্ড এবং রেঞ্জ_স্টার্ট নামক কলাম রয়েছে, সমস্ত মিলে যাওয়া সারিগুলি পুনরুদ্ধার করার জন্য এখানে কিছু সাধারণ এসকিউএল দেওয়া হয়েছে:

SELECT *
FROM periods
WHERE NOT (range_start > @check_period_end
           OR range_end < @check_period_start)

উল্লেখ্য নয় ওখানে। যেহেতু দুটি সহজ নিয়ম সমস্ত মিলহীন সারিগুলি সন্ধান করে, একটি সরল নট এটি বলার জন্য বিপরীত হবে: এটি যদি মিল না করা সারিগুলির মধ্যে একটি না হয় তবে এটি ম্যাচিংয়ের মধ্যে একটি হতে হবে

নোট থেকে পরিত্রাণ পেতে এখানে সাধারণ বিপরীত যুক্তি প্রয়োগ করা এবং আপনি এটি শেষ করবেন:

SELECT *
FROM periods
WHERE range_start <= @check_period_end
      AND range_end >= @check_period_start

45
উত্তরগুলির জন্য আমাদের একটি "এসিআইআই ডায়াগ্রামগুলি" পতাকা লাগবে যা আপনাকে সেগুলি একাধিকবার উপড়ে ফেলতে দেয়
জনি বুচানান

29
সম্ভবত আমি এসওতে দেখা 5 টি সেরা উত্তরগুলির মধ্যে একটি। সমস্যার দুর্দান্ত ব্যাখ্যা, সমাধানের দুর্দান্ত ওয়াকথ্রু এবং ... ছবিগুলি!
ডেভিডাবার

10
আমি যদি একাধিকবার এটিকে ভোট দিতে পারি তবে আমি করতাম। একটি সাধারণ সমস্যা প্রকাশিত হওয়ার দুর্দান্ত, স্পষ্ট এবং সংক্ষিপ্ত ব্যাখ্যা, এমন একটি সমাধান যা আমি খুব কমই এত সুন্দরভাবে ব্যাখ্যা করেছি!
কনরোয়পি

2
দুর্দান্ত উত্তর! কেবলমাত্র আমি যুক্ত করব - শেষ পয়েন্টগুলি অন্তর্ভুক্ত রয়েছে কিনা তা নির্ধারণের প্রসঙ্গে - আপনি যদি একপাশে একটি বন্ধ ব্যবধান এবং অন্যদিকে একটি খোলা ব্যবধান নিয়ে যান তবে সবকিছু পরিষ্কার হয়ে যায়। উদাহরণস্বরূপ, একটি ব্যাপ্তির শুরুতে বিন্দুতে অন্তর্ভুক্ত থাকে এবং পরিসীমাটির শেষ হয় না। বিশেষত যখন আপনি খেজুর এবং বিভিন্ন রেজোলিউশনের সংমিশ্রণ নিয়ে কাজ করছেন, তখন সবকিছু সহজ হয়ে যায়।
অন্ধকার

1
ভাল উত্তর. এটি অ্যালেনের অন্তর্বর্তী বীজগণিত হিসাবেও বর্ণনা করা হয় । আমার একটি অনুরূপ উত্তর রয়েছে এবং একজন ভাষ্যকারের সাথে কয়টি আলাদা তুলনা রয়েছে তা নিয়ে মারাত্মক লড়াইয়ে নেমেছি।
জোনাথন লেফলার

8

আপনার 06/06/1983 থেকে 18/06/1983 এর উদাহরণ পরিসীমা গ্রহণ করে এবং ধরে নেওয়া যে আপনার রেঞ্জগুলির জন্য শুরু এবং শেষের মতো কলাম রয়েছে, আপনি এই জাতীয় একটি ধারা ব্যবহার করতে পারেন

where ('1983-06-06' <= end) and ('1983-06-18' >= start)

উদাহরণস্বরূপ, আপনার পরীক্ষার পরিসীমাটির শুরুটি ডাটাবেস সীমা শেষ হওয়ার আগে এবং আপনার পরীক্ষার সীমাটির শেষটি ডাটাবেস সীমাটির পরে বা শুরুতে হয় তা পরীক্ষা করুন।


4

যদি আপনার আরডিবিএমএস ওভারল্যাপ () ফাংশনটিকে সমর্থন করে তবে এটি তুচ্ছ হয়ে ওঠে - হোমগ্রাউন সমাধানের প্রয়োজন নেই। (ওরাকল এ এটি পরিষ্কারভাবে কাজ করে তবে নথিভুক্ত নয়)।


1
মহাকাব্য সমাধান। ঠিকভাবে কাজ করে. এটি ওরাকলে 2 তারিখ ব্যাপ্তির (এস 1, ই 1) এবং (এস 2, ই 2) সিনট্যাক্স: দ্বৈত যেখানে 1 (এস 1, ই 1) ওভারল্যাপগুলি (এস 2, ই 2) থেকে 1 নির্বাচন করুন;
ইহেবিহব

0

আপনার প্রত্যাশিত ফলাফলগুলিতে আপনি বলেছেন

06/06/1983 থেকে 18/06/1983 = IN তালিকাতে

যাইহোক, এই পিরিয়ডটি আপনার টেবিলের (পিরিয়ডগুলির তালিকা নয়!) পিরিয়ডগুলির কোনও সহ থাকে না বা থাকে না। এটি অবশ্য 10/06/1983 থেকে 14/06/1983 সময়কালকে ওভারল্যাপ করে।

আপনি স্নোডগ্রাস বইটি ( http://www.cs.arizona.edu/people/rts/tdbbook.pdf ) দরকারী খুঁজে পেতে পারেন : এটি মাইএসকিএল-এর প্রাক-তারিখ রয়েছে তবে সময়ের ধারণাটি পরিবর্তিত হয়নি ;-)


0

আমি মাইএসকিউএলে এই সমস্যাটি মোকাবেলায় ফাংশন তৈরি করেছি। ব্যবহারের আগে সেকেন্ডে তারিখগুলি রূপান্তর করুন।

DELIMITER ;;

CREATE FUNCTION overlap_interval(x INT,y INT,a INT,b INT)
RETURNS INTEGER DETERMINISTIC
BEGIN
DECLARE
    overlap_amount INTEGER;
    IF (((x <= a) AND (a < y)) OR ((x < b) AND (b <= y)) OR (a < x AND y < b)) THEN
        IF (x < a) THEN
            IF (y < b) THEN
                SET overlap_amount = y - a;
            ELSE
                SET overlap_amount = b - a;
            END IF;
        ELSE
            IF (y < b) THEN
                SET overlap_amount = y - x;
            ELSE
                SET overlap_amount = b - x;
            END IF;
        END IF;
    ELSE
        SET overlap_amount = 0;
    END IF;
    RETURN overlap_amount;
END ;;

DELIMITER ;

0

নিম্নলিখিত উদাহরণটি দেখুন। এটি আপনার জন্য সহায়ক হবে।

    SELECT  DISTINCT RelatedTo,CAST(NotificationContent as nvarchar(max)) as NotificationContent,
                ID,
                Url,
                NotificationPrefix,
                NotificationDate
                FROM NotificationMaster as nfm
                inner join NotificationSettingsSubscriptionLog as nfl on nfm.NotificationDate between nfl.LastSubscribedDate and isnull(nfl.LastUnSubscribedDate,GETDATE())
  where ID not in(SELECT NotificationID from removednotificationsmaster where Userid=@userid) and  nfl.UserId = @userid and nfl.RelatedSettingColumn = RelatedTo

0

এমএস এসকিউএল এ চেষ্টা করুন


WITH date_range (calc_date) AS (
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, [ending date]) - DATEDIFF(DAY, [start date], [ending date]), 0)
UNION ALL SELECT DATEADD(DAY, 1, calc_date)
FROM date_range 
WHERE DATEADD(DAY, 1, calc_date) <= [ending date])
SELECT  P.[fieldstartdate], P.[fieldenddate]
FROM date_range R JOIN [yourBaseTable] P on Convert(date, R.calc_date) BETWEEN convert(date, P.[fieldstartdate]) and convert(date, P.[fieldenddate]) 
GROUP BY  P.[fieldstartdate],  P.[fieldenddate];


0

BETWEEN স্কয়ার স্টেটমেন্ট ব্যবহার করে অন্য পদ্ধতি

পিরিয়ডস অন্তর্ভুক্ত:

SELECT *
FROM periods
WHERE @check_period_start BETWEEN range_start AND range_end
  AND @check_period_end BETWEEN range_start AND range_end

পিরিয়ড বাদ:

SELECT *
FROM periods
WHERE (@check_period_start NOT BETWEEN range_start AND range_end
  OR @check_period_end NOT BETWEEN range_start AND range_end)

-2
SELECT * 
FROM tabla a 
WHERE ( @Fini <= a.dFechaFin AND @Ffin >= a.dFechaIni )
  AND ( (@Fini >= a.dFechaIni AND @Ffin <= a.dFechaFin) OR (@Fini >= a.dFechaIni AND @Ffin >= a.dFechaFin) OR (a.dFechaIni>=@Fini AND a.dFechaFin <=@Ffin) OR
(a.dFechaIni>=@Fini AND a.dFechaFin >=@Ffin) )

স্ট্যাক ওভারফ্লোতে স্বাগতম! এই কোড স্নিপেটের জন্য আপনাকে ধন্যবাদ, যা কিছু তাত্ক্ষণিক সহায়তা সরবরাহ করতে পারে। একটি সঠিক ব্যাখ্যা কেন এটি সমস্যার একটি ভাল সমাধান তা দেখিয়ে তার শিক্ষাগত মানকে ব্যাপকভাবে উন্নত করবে এবং ভবিষ্যতের পাঠকদের জন্য একই, তবে অভিন্ন নয়, এমন প্রশ্নের সাথে আরও দরকারী করে তুলবে। দয়া করে ব্যাখ্যা যুক্ত করতে আপনার উত্তর সম্পাদনা করুন, এবং কোন সীমাবদ্ধতা এবং অনুমানগুলি প্রযোজ্য তা একটি ইঙ্গিত দিন।
টবির স্পিড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.