দুটি তারিখের মধ্যে তারিখগুলির একটি তালিকা পান


91

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

উদাহরণস্বরূপ, ২০০৯-০১-০১ এবং ২০০৯-০১-১৩ প্রদত্ত মানগুলির সাথে এটি একটি কলামের সারণী ফেরত দেবে:

 2009-01-01 
 2009-01-02 
 2009-01-03
 2009-01-04 
 2009-01-05
 2009-01-06
 2009-01-07
 2009-01-08 
 2009-01-09
 2009-01-10
 2009-01-11
 2009-01-12
 2009-01-13

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


4
আমি সবচেয়ে ভালো সমাধান উত্তর বর্ণনা করা হয় মনে stackoverflow.com/a/2157776/466677
Marek গ্রেগর

উত্তর:


68

টাইম_ইনটার্ভাল নামক টেম্প টেবিলটিতে আপনার প্রয়োজনীয় অন্তরগুলি তৈরি করতে আমি এই সঞ্চিত পদ্ধতিটি ব্যবহার করব , তারপরে যোগদান করুন এবং টেম্প টাইম_ইন্টারভালস টেবিলের সাথে আপনার ডেটা টেবিলকে একত্রিত করুন ।

পদ্ধতিটি এতে উল্লিখিত সমস্ত বিভিন্ন ধরণের অন্তর তৈরি করতে পারে:

call make_intervals('2009-01-01 00:00:00','2009-01-10 00:00:00',1,'DAY')
.
select * from time_intervals  
.
interval_start      interval_end        
------------------- ------------------- 
2009-01-01 00:00:00 2009-01-01 23:59:59 
2009-01-02 00:00:00 2009-01-02 23:59:59 
2009-01-03 00:00:00 2009-01-03 23:59:59 
2009-01-04 00:00:00 2009-01-04 23:59:59 
2009-01-05 00:00:00 2009-01-05 23:59:59 
2009-01-06 00:00:00 2009-01-06 23:59:59 
2009-01-07 00:00:00 2009-01-07 23:59:59 
2009-01-08 00:00:00 2009-01-08 23:59:59 
2009-01-09 00:00:00 2009-01-09 23:59:59 
.
call make_intervals('2009-01-01 00:00:00','2009-01-01 02:00:00',10,'MINUTE')
. 
select * from time_intervals
.  
interval_start      interval_end        
------------------- ------------------- 
2009-01-01 00:00:00 2009-01-01 00:09:59 
2009-01-01 00:10:00 2009-01-01 00:19:59 
2009-01-01 00:20:00 2009-01-01 00:29:59 
2009-01-01 00:30:00 2009-01-01 00:39:59 
2009-01-01 00:40:00 2009-01-01 00:49:59 
2009-01-01 00:50:00 2009-01-01 00:59:59 
2009-01-01 01:00:00 2009-01-01 01:09:59 
2009-01-01 01:10:00 2009-01-01 01:19:59 
2009-01-01 01:20:00 2009-01-01 01:29:59 
2009-01-01 01:30:00 2009-01-01 01:39:59 
2009-01-01 01:40:00 2009-01-01 01:49:59 
2009-01-01 01:50:00 2009-01-01 01:59:59 
.
I specified an interval_start and interval_end so you can aggregate the 
data timestamps with a "between interval_start and interval_end" type of JOIN.
.
Code for the proc:
.
-- drop procedure make_intervals
.
CREATE PROCEDURE make_intervals(startdate timestamp, enddate timestamp, intval integer, unitval varchar(10))
BEGIN
-- *************************************************************************
-- Procedure: make_intervals()
--    Author: Ron Savage
--      Date: 02/03/2009
--
-- Description:
-- This procedure creates a temporary table named time_intervals with the
-- interval_start and interval_end fields specifed from the startdate and
-- enddate arguments, at intervals of intval (unitval) size.
-- *************************************************************************
   declare thisDate timestamp;
   declare nextDate timestamp;
   set thisDate = startdate;

   -- *************************************************************************
   -- Drop / create the temp table
   -- *************************************************************************
   drop temporary table if exists time_intervals;
   create temporary table if not exists time_intervals
      (
      interval_start timestamp,
      interval_end timestamp
      );

   -- *************************************************************************
   -- Loop through the startdate adding each intval interval until enddate
   -- *************************************************************************
   repeat
      select
         case unitval
            when 'MICROSECOND' then timestampadd(MICROSECOND, intval, thisDate)
            when 'SECOND'      then timestampadd(SECOND, intval, thisDate)
            when 'MINUTE'      then timestampadd(MINUTE, intval, thisDate)
            when 'HOUR'        then timestampadd(HOUR, intval, thisDate)
            when 'DAY'         then timestampadd(DAY, intval, thisDate)
            when 'WEEK'        then timestampadd(WEEK, intval, thisDate)
            when 'MONTH'       then timestampadd(MONTH, intval, thisDate)
            when 'QUARTER'     then timestampadd(QUARTER, intval, thisDate)
            when 'YEAR'        then timestampadd(YEAR, intval, thisDate)
         end into nextDate;

      insert into time_intervals select thisDate, timestampadd(MICROSECOND, -1, nextDate);
      set thisDate = nextDate;
   until thisDate >= enddate
   end repeat;

 END;

এই পোস্টের নীচে একই রকমের ডেটা দৃশ্যাবলী , যেখানে আমি এসকিউএল সার্ভারের জন্য অনুরূপ ফাংশন তৈরি করেছি।


4
আমি ব্যক্তিগতভাবে পোস্টগ্র্রেএসকিউএল এ উত্পন্ন সিকোয়েন্সগুলির অনুরূপ কিছু প্রত্যাশী ছিলাম।
ফিলিপ হিলান

যদি আপনি একবার ডেটা তৈরি করে থাকেন তবে আপনি স্থায়ী টেবিলগুলি ব্যবহার করতে এবং হারিয়ে যাওয়া তারিখগুলি পূরণ করতে এই স্ক্রিপ্টটি ব্যবহার করতে পারেন।
বিমল পাউদেল

পিএইচপিএমওয়াই অ্যাডমিনের মাধ্যমে এটি কার্যকর করার জন্য আমাকে ক্রিয়াকলাপের বিবৃতি তৈরি করার আগে ডিলিমিটারটি পরিবর্তন করতে হয়েছিল (বিবৃতিতে সিনট্যাক্স ত্রুটি এড়াতে) [কোড] ডিক্লার // [/ কোড]
Defkon1

এই সমাধানটি খুব শক্তিশালী এবং নমনীয়, অপ্রত্যাশিতভাবে মারিয়া ডিবিতে আমি ত্রুটিটি পেয়ে যাচ্ছি # 1067 - কল মেকিং_আন্টারভ্যালস চলাকালীন 'ইন্টারভাল_েন্ড' এর জন্য অবৈধ ডিফল্ট মান ('২০০৯-০১-০১ 00:00:00', '২০০৯-০১-১০ 00: 00: 00 ', 1,' দিন '); আমি 5...2.২৮ সংস্করণে রয়েছি
শেলবিপায়েরের

28

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

আপনি এটিকে একটি টেবিলের মূল্যবান ফাংশনটিতে গুটিয়ে রাখতে পারেন বা ভেরিয়েবল হিসাবে প্রারম্ভ এবং শেষের তারিখগুলিতে পার্স করতে পারেন।

DECLARE @startDate DATETIME
DECLARE @endDate DATETIME

SET @startDate = '2011-01-01'
SET @endDate = '2011-01-31';

WITH dates(Date) AS 
(
    SELECT @startdate as Date
    UNION ALL
    SELECT DATEADD(d,1,[Date])
    FROM dates 
    WHERE DATE < @enddate
)

SELECT Date
FROM dates
OPTION (MAXRECURSION 0)
GO

4
এখানে বিকল্প (MAXRECURSION 0) এর ব্যবহার কী?
শিব

14

বিআইআরটি রিপোর্টগুলির সাথে আমাদের একই রকম সমস্যা ছিল যে আমরা সেই দিনগুলিতে রিপোর্ট করতে চেয়েছিলাম যার কোনও ডেটা ছিল না। যেহেতু dates তারিখগুলির জন্য কোনও প্রবেশিকা ছিল না, তাই আমাদের জন্য সবচেয়ে সহজ সমাধানটি ছিল একটি সাধারণ টেবিল তৈরি করা যা সমস্ত তারিখ সঞ্চিত করে এবং ব্যাপ্তি পেতে বা সেই তারিখের শূন্য মান পেতে যোগ দেওয়ার জন্য ব্যবহার করে।

ভবিষ্যতে টেবিলটি 5 বছরের আবাসস্থল রয়েছে কিনা তা নিশ্চিত করার জন্য আমাদের প্রতি মাসে একটি কাজ রয়েছে। টেবিলটি এভাবে তৈরি করা হয়েছে:

create table all_dates (
    dt date primary key
);

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

অন্য বিকল্পটি (এবং আমরা এটি আগেও ব্যবহার করেছি) হ'ল প্রতিটি তারিখের টেবিলে কোনও প্রবেশ রয়েছে কিনা তা নিশ্চিত করা। আমরা পর্যায়ক্রমে সারণীটি সরিয়ে নিয়েছি এবং তারিখ এবং / অথবা যেগুলির অস্তিত্ব ছিল না তার জন্য শূন্য এন্ট্রি যুক্ত করেছি। এটি আপনার ক্ষেত্রে বিকল্প নাও হতে পারে, এটি সঞ্চিত ডেটার উপর নির্ভর করে।

আপনি যদি সত্যিই ভাবেন যে all_datesটেবিলটিকে জনবহুল রাখতে সমস্যা হ'ল, একটি সঞ্চিত পদ্ধতি হ'ল উপায় যা সেই তারিখগুলি সহ একটি ডেটাসেট ফেরত দেবে। এটি প্রায় অবশ্যই ধীর হবে কারণ আপনাকে প্রতিবার যখন ডাকা হয় তখন কেবল সারণি থেকে প্রাক-গণনা করা ডেটা টানানোর পরিবর্তে কল করতে হয়।

তবে, সত্যি বলতে কী, আপনি কোনও গুরুতর ডেটা স্টোরেজ সমস্যা ছাড়াই 1000 বছর ধরে টেবিলটি তৈরি করতে পারেন - 365,000 16-বাইট (উদাহরণস্বরূপ) তারিখগুলি এবং সুরক্ষার জন্য তারিখটি 20% ওভারহেডের অনুলিপি করে থাকে, আমি মোটামুটি অনুমান করতে পারি প্রায় 14 এম [365,000 * 16 * 2 * 1.2 = 14,016,000 বাইট]], জিনিসগুলির স্কিমের একটি বিয়োগফল টেবিল।


12

আপনি মাইএসকিউএল এর ব্যবহারকারীর ভেরিয়েবলগুলি এর মতো ব্যবহার করতে পারেন :

SET @num = -1;
SELECT DATE_ADD( '2009-01-01', interval @num := @num+1 day) AS date_sequence, 
your_table.* FROM your_table
WHERE your_table.other_column IS NOT NULL
HAVING DATE_ADD('2009-01-01', interval @num day) <= '2009-01-13'

@ সংখ্যাটি -1 হ'ল কারণ আপনি এটি যুক্ত করার সময় প্রথম যুক্ত করেন। এছাড়াও, আপনি "HAVING তারিখ_সিকোয়েন্স" ব্যবহার করতে পারবেন না কারণ এটি প্রতিটি সারির জন্য দুবার ব্যবহারকারীর পরিবর্তনশীল বৃদ্ধি করে।


8

এই উত্তর থেকে ধারণা নেওয়া , আপনি 0 থেকে 9 দিয়ে একটি সারণী সেট আপ করতে পারেন এবং এটি আপনার তারিখের তালিকা তৈরি করতে ব্যবহার করতে পারেন।

CREATE TABLE num (i int);
INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);

select adddate('2009-01-01', numlist.id) as `date` from
(SELECT n1.i + n10.i*10 + n100.i*100 AS id
   FROM num n1 cross join num as n10 cross join num as n100) as numlist
where adddate('2009-01-01', numlist.id) <= '2009-01-13';

এটি আপনাকে 1000 তারিখের একটি তালিকা তৈরি করতে দেয়। আপনার যদি আরও বড় হওয়ার দরকার হয় তবে আপনি অভ্যন্তরীণ কোয়েরিতে আরও একটি ক্রস যুক্ত যুক্ত করতে পারেন।


এই সমাধানটি আরও ভাল কাজ করে। তবে এটিতে UNIX_TIMESTAMP () এর সাথে একটি সমস্যা রয়েছে - এটি 1231185600.000000 এর মতো ফলাফল দেয়; দশমিক বিন্দু পরে মিলিসেকেন্ড অংশ; যখন - নির্বাচন করুন UNIX_TIMESTAMP (ADDDATE ('৯৯-০১-০১ ', ০)) এএস date; অংশ না ফলাফল।
বিমল পাউদেল

3

অ্যাক্সেসের জন্য (বা কোনও এসকিউএল ভাষা)

  1. একটি ক্ষেত্র তৈরি করুন যার 2 টি ক্ষেত্র রয়েছে, আমরা এই টেবিলটিকে কল করব tempRunDates: -
    ফিল্ডস fromDateএবং - toDate
    তারপরে কেবল 1 টি রেকর্ড সন্নিবেশ করান, যার শুরু তারিখ এবং শেষ তারিখ রয়েছে।

  2. অন্য একটি সারণী তৈরি করুন: Time_Day_Ref
    - এই টেবিলটিতে তারিখের একটি তালিকা (এক্সেলের তালিকা তৈরি করা সহজ) mp
    - আমার ক্ষেত্রে ক্ষেত্রের নামটি Greg_Dtগ্রেগরিয়ান তারিখের
    জন্য - আমি জানুয়ারী 1 2009 থেকে জানুয়ারীতে 2020 এর মাধ্যমে আমার তালিকা তৈরি করেছি।

  3. ক্যোয়ারী চালান:

    SELECT Time_Day_Ref.GREG_DT
    FROM tempRunDates, Time_Day_Ref
    WHERE Time_Day_Ref.greg_dt>=tempRunDates.fromDate And greg_dt<=tempRunDates.toDate;
    

সহজ!


2

সাধারণত কেউ একটি সহায়ক সংখ্যার টেবিল ব্যবহার করবে যা আপনি সাধারণত এই উদ্দেশ্যে কিছুটা প্রকারের সাথে রাখেন:

SELECT *
FROM (
    SELECT DATEADD(d, number - 1, '2009-01-01') AS dt
    FROM Numbers
    WHERE number BETWEEN 1 AND DATEDIFF(d, '2009-01-01', '2009-01-13') + 1
) AS DateRange
LEFT JOIN YourStuff
    ON DateRange.dt = YourStuff.DateColumn

আমি টেবিল-মূল্যবান ফাংশন ইত্যাদির সাথে বিভিন্নতা দেখেছি etc.

আপনি তারিখের স্থায়ী তালিকা রাখতে পারেন। আমাদের সেই ডেটা গুদামের পাশাপাশি দিনের সময়ের তালিকাগুলিতে রয়েছে।


2

এসকিউএল সার্ভারে প্রদত্ত দুটি তারিখের মধ্যে তারিখগুলি কীভাবে সন্ধান করতে হয় তা http://ektaraval.blogspot.com/2010/09/writing-recursive-query-to-find-out-all.html এ ব্যাখ্যা করা হবে


4
মাইএসকিউএল এখনও পুনরাবৃত্ত অনুসন্ধানগুলি সমর্থন করে না, সুতরাং এই সমাধানটি এখানে ব্যবহার করা যায় না।
মার্ক বাইয়ার্স

2
CREATE FUNCTION [dbo].[_DATES]
(
    @startDate DATETIME,
    @endDate DATETIME
)
RETURNS 
@DATES TABLE(
    DATE1 DATETIME
)
AS
BEGIN
    WHILE @startDate <= @endDate
    BEGIN 
        INSERT INTO @DATES (DATE1)
            SELECT @startDate   
    SELECT @startDate = DATEADD(d,1,@startDate) 
    END
RETURN
END

2

মারিয়াডিবি> = 10.3 এবং মাইএসকিউএল> = 8.0 এ নতুন পুনরাবৃত্ত (সাধারণ টেবিল এক্সপ্রেশন) কার্যকারিতা ব্যবহার করে মার্জিত সমাধান।

WITH RECURSIVE t as (
    select '2019-01-01' as dt
  UNION
    SELECT DATE_ADD(t.dt, INTERVAL 1 DAY) FROM t WHERE DATE_ADD(t.dt, INTERVAL 1 DAY) <= '2019-04-30'
)
select * FROM t;

উপরেরগুলি '2019-01-01' এবং '2019-04-30' এর মধ্যে তারিখের একটি সারণী দেয়।


"2019-01-01 'কে dt হিসাবে নির্বাচন করুন" এই নির্বাচকটি কী? কেবলমাত্র একটি থেকে এবং ফিল্ডে নির্বাচন করা কি সম্ভব?
মিগুয়েল স্টিভেনস

1

আমরা এটি আমাদের এইচআরএমএস সিস্টেমে ব্যবহার করেছি আপনি এটি দরকারী হিসাবে ব্যবহার করবেন

SELECT CAST(DAYNAME(daydate) as CHAR) as dayname,daydate
    FROM
    (select CAST((date_add('20110101', interval H.i*100 + T.i*10 + U.i day) )as DATE) as daydate
      from erp_integers as H
    cross
      join erp_integers as T
    cross
      join erp_integers as U
     where date_add('20110101', interval H.i*100 + T.i*10 + U.i day ) <= '20110228'
    order
        by daydate ASC
        )Days

1

এই সমাধানটি মাইএসকিউএল 5.0 এর সাথে কাজ করছে
একটি সারণী তৈরি করুন - mytable
স্কিমা উপাদান নয়। কী গুরুত্বপূর্ণ তা হল এতে সারি সংখ্যা।
সুতরাং, আপনি 10 টি সারি, মান - 1 থেকে 10 সহ টাইপ করুন মাত্র এক কলাম রাখতে পারেন।

এসকিউএল:

set @tempDate=date('2011-07-01') - interval 1 day;
select
date(@tempDate := (date(@tempDate) + interval 1 day)) as theDate
from mytable x,mytable y
group by theDate
having theDate <= '2011-07-31';

সীমাবদ্ধতা: উপরের ক্যোয়ারী দ্বারা ফিরে আসা তারিখগুলির সর্বাধিক সংখ্যা হবে
(rows in mytable)*(rows in mytable) = 10*10 = 100.

আপনি
বর্গক্ষেত্রে ফর্ম অংশ পরিবর্তন করে এই ব্যাপ্তিটি বাড়িয়ে তুলতে পারেন: Mytable x থেকে, mytable y, mytable z
সুতরাং, পরিসীমাটি আরও 10*10*10 =1000অনেক কিছু।


0

A_begin এবং a_end দুটি পরামিতি লাগে এমন একটি সঞ্চিত পদ্ধতি তৈরি করুন। এর মধ্যে টি নামে একটি অস্থায়ী সারণী তৈরি করুন, একটি ভেরিয়েবল ডি ঘোষণা করুন, ডি-তে a_begin বরাদ্দ করুন, এবং একটি WHILEলুপ আইং ডি টিতে চালান INSERTএবং ADDDATEমান ডি বাড়ানোর জন্য কলিং ফাংশন। অবশেষে SELECT * FROM t


প্রকৃতপক্ষে আমি বিশ্বাস করি স্থায়ী টেবিল কার্যকর করার গতির জন্য ভাল হবে (ন্যূনতম সঞ্চয়ের প্রয়োজনীয়তা রয়েছে)। আপনার প্রয়োজন অনুযায়ী প্রতিবার রেঞ্জ তৈরি করার চেয়ে কোনও টেবিলের মধ্যে তারিখগুলি প্রাক-গণনা করা এবং যখন প্রয়োজন হয় তখন উত্তোলন করা দ্রুত।
paxdiablo

@ প্যাক্স, এটি নির্ভর করে যদি অর্জিত গতির উন্নতি টেবিল রক্ষণাবেক্ষণের পক্ষে মূল্যবান হয়। উদাহরণস্বরূপ, যদি প্রতিবেদন প্রজন্মটি 3 সেকেন্ড সময় নেয় এবং তারিখগুলি তৈরি করতে WHILE লুপটি চালাতে 0.001 সেকেন্ড সময় লাগে, আমি যুক্তি দেব যে পারফরম্যান্স লাভটি উপেক্ষাযোগ্য। নুথ: অকালীন অপটিমাইজেশন হ'ল সমস্ত অশুভের মূল।
ইউজিন ইয়োকোটা

@ eed3si9n, অকাল অপটিমাইজেশন, হ্যাঁ, সমস্ত অপ্টিমাইজেশন নয় :-) আপনার উদাহরণটি যদি সঠিক হয় তবে হ্যাঁ, আমি আপনার সাথে একমত হব, তবে এটি অবশ্যই নিশ্চিত হওয়া উচিত। আমার পরামর্শ অনুসারে আপনি যদি এটি 1000 বছর বাইরে (এক সময়ের মূল্য) তৈরি করেন সারণী রক্ষণাবেক্ষণটি চলে গেছে তবে সেই সেকেন্ডগুলি যোগ হয়ে যাবে।
paxdiablo

0

আমি এর অনুরূপ কিছু ব্যবহার করব:

DECLARE @DATEFROM AS DATETIME
DECLARE @DATETO AS DATETIME
DECLARE @HOLDER TABLE(DATE DATETIME)

SET @DATEFROM = '2010-08-10'
SET @DATETO = '2010-09-11'

INSERT INTO
    @HOLDER
        (DATE)
VALUES
    (@DATEFROM)

WHILE @DATEFROM < @DATETO
BEGIN

    SELECT @DATEFROM = DATEADD(D, 1, @DATEFROM)
    INSERT 
    INTO
        @HOLDER
            (DATE)
    VALUES
        (@DATEFROM)
END

SELECT 
    DATE
FROM
    @HOLDER

তারপরে @HOLDERভেরিয়েবল টেবিলটি সেই দুটি তারিখের মধ্যে দিনের সাথে বাড়ানো সমস্ত তারিখগুলি ধারণ করে, আপনার হৃদয়ের সামগ্রীতে যোগ দিতে প্রস্তুত।


হ্যালো, আমি কোডটি ব্যবহার করার চেষ্টা করছি এবং আউটপুটটি একটি টেবিলের মধ্যে সন্নিবেশ করানোর জন্য আমি তারিখ টেস্টকে DATETIME টাইপের কলামের তারিখফিল দিয়ে সংজ্ঞায়িত করেছি ... তবে ব্যর্থ হচ্ছে ... আপনি কি দয়া করে কোডটি সরবরাহ করতে পারবেন? দ্রষ্টব্য: এসকিউএল সার্ভার ব্যবহার করে এখানে ধন্যবাদ :)
sys_debug

0

আমি বেশ কিছুদিন ধরে এটার সাথে লড়াই করছি। যেহেতু আমি যখন গুগলটিতে সমাধানটি অনুসন্ধান করেছি এটিই প্রথম হিট, তাই এখন পর্যন্ত কোথায় পৌঁছেছি তা আমাকে পোস্ট করুন।

SET @d := '2011-09-01';
SELECT @d AS d, cast( @d := DATE_ADD( @d , INTERVAL 1 DAY ) AS DATE ) AS new_d
  FROM [yourTable]
  WHERE @d <= '2012-05-01';

[yourTable]আপনার ডাটাবেস থেকে একটি টেবিল দিয়ে প্রতিস্থাপন করুন । কৌশলটি হ'ল আপনি সারণীতে যে সারিগুলির সংখ্যা নির্বাচন করেছেন তা অবশ্যই> = আপনি ফিরে আসতে চান এমন তারিখের সংখ্যা। আমি টেবিলের স্থানধারক ডুয়াল ব্যবহার করার চেষ্টা করেছি, তবে এটি কেবল একটি একক সারিতে ফিরবে।


4
আকর্ষণীয় পদ্ধতির। তবে .. এই মূলত বিহং উপরে কি পরামর্শ দিয়েছে?)?
লে

0
select * from table_name where col_Date between '2011/02/25' AND DATEADD(s,-1,DATEADD(d,1,'2011/02/27'))

এখানে, বর্তমানের শেষ তারিখটিতে প্রথমে একটি দিন যুক্ত করুন, এটি ২০১০-০২-২৮ 00:00:00 হবে, তারপরে আপনি শেষের তারিখটি তৈরি করতে এক সেকেন্ডটি বিয়োগ করুন 2011-02-27 23:59:59। এটি করে আপনি প্রদত্ত বিরতিগুলির মধ্যে সমস্ত তারিখ পেতে পারেন।

আউটপুট:
2011/02/25
2011/02/26
2011/02/27


0
DELIMITER $$  
CREATE PROCEDURE popula_calendario_controle()
   BEGIN
      DECLARE a INT Default 0;
      DECLARE first_day_of_year DATE;
      set first_day_of_year = CONCAT(DATE_FORMAT(curdate(),'%Y'),'-01-01');
      one_by_one: LOOP
         IF dayofweek(adddate(first_day_of_year,a)) <> 1 THEN
            INSERT INTO calendario.controle VALUES(null,150,adddate(first_day_of_year,a),adddate(first_day_of_year,a),1);
         END IF;
         SET a=a+1;
         IF a=365 THEN
            LEAVE one_by_one;
         END IF;
      END LOOP one_by_one;
END $$

এই পদ্ধতিটি বছরের শুরু থেকে এখন অবধি সমস্ত তারিখ সন্নিবেশ করবে, কেবল "শুরু" এবং "শেষ" এর দিনগুলিকে প্রতিস্থাপন করুন এবং আপনি যেতে প্রস্তুত!


IF a=365 THENলিপ বছরগুলিতে কীভাবে প্রভাবিত হয়?
স্টুয়ার্ট

এছাড়াও, 1509 লাইনে সংখ্যার তাত্পর্য কি ? এই কোডটি খুব প্রকৃত ব্যাখ্যা ছাড়াই একটি "প্যাট উত্তর"।
স্টুয়ার্ট

0

আমার পরিসংখ্যানের জন্য 2 তারিখের মধ্যে সমস্ত মাস সহ একটি তালিকা প্রয়োজন। 2 তারিখগুলি সাবস্ক্রিপশন থেকে শুরু এবং শেষ তারিখ d সুতরাং তালিকাটি সমস্ত মাস এবং প্রতি মাসে সদস্যতার পরিমাণ দেখায়।

MYSQL

CREATE PROCEDURE `get_amount_subscription_per_month`()
BEGIN
   -- Select the ultimate start and enddate from subscribers
   select @startdate := min(DATE_FORMAT(a.startdate, "%Y-%m-01")), 
          @enddate := max(DATE_FORMAT(a.enddate, "%Y-%m-01")) + interval 1 MONTH
   from subscription a;

   -- Tmp table with all months (dates), you can always format them with DATE_FORMAT) 
   DROP TABLE IF EXISTS tmp_months;
   create temporary table tmp_months (
      year_month date,
      PRIMARY KEY (year_month)
   );


   set @tempDate=@startdate;  #- interval 1 MONTH;

   -- Insert every month in tmp table
   WHILE @tempDate <= @enddate DO
     insert into tmp_months (year_month) values (@tempDate);
     set @tempDate = (date(@tempDate) + interval 1 MONTH);
   END WHILE;

   -- All months
   select year_month from tmp_months;

   -- If you want the amount of subscription per month else leave it out
   select mnd.year_month, sum(subscription.amount) as subscription_amount
   from tmp_months mnd
   LEFT JOIN subscription ON mnd.year_month >= DATE_FORMAT(subscription.startdate, "%Y-%m-01") and mnd.year_month <= DATE_FORMAT(subscription.enddate, "%Y-%m-01")
   GROUP BY mnd.year_month;

 END

0

আপনি এটি ব্যবহার করতে পারেন

SELECT CAST(cal.date_list AS DATE) day_year
FROM (
  SELECT SUBDATE('2019-01-01', INTERVAL 1 YEAR) + INTERVAL xc DAY AS date_list
  FROM (
        SELECT @xi:=@xi+1 as xc from
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc1,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc2,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc3,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc4,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) xc5,
        (SELECT @xi:=-1) xc0
    ) xxc1
) cal
WHERE cal.date_list BETWEEN '2019-01-01' AND '2019-12-31'
ORDER BY cal.date_list DESC;


-2

আমি ব্যাবহার করছি Server version: 5.7.11-log MySQL Community Server (GPL)

এখন আমরা এটি একটি সহজ উপায়ে সমাধান করব।

আমি "তারিখের টেবিল " নামে একটি সারণী তৈরি করেছি

mysql> describe datetable;
+---------+---------+------+-----+---------+-------+
| Field   | Type    | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| colid   | int(11) | NO   | PRI | NULL    |       |
| coldate | date    | YES  |     | NULL    |       |
+---------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

এখন, সপ্তাহের মধ্যে সন্নিবেশ করা রেকর্ডগুলি দেখতে পাবেন।

mysql> select * from datetable;
+-------+------------+
| colid | coldate    |
+-------+------------+
|   101 | 2015-01-01 |
|   102 | 2015-05-01 |
|   103 | 2016-01-01 |
+-------+------------+
3 rows in set (0.00 sec)

এবং আমাদের তারিখগুলির চেয়ে দুটি তারিখের মধ্যে রেকর্ড আনার জন্য আমাদের ক্যোয়ারী।

mysql> select * from datetable where coldate > '2015-01-01' and coldate < '2016-01-01';
+-------+------------+
| colid | coldate    |
+-------+------------+
|   102 | 2015-05-01 |
+-------+------------+
1 row in set (0.00 sec)

আশা করি এটি অনেককে সহায়তা করবে।


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