Postgresql এ তারিখের সময় ক্ষেত্রগুলির তারিখগুলি কীভাবে তুলনা করবেন?


186

পোস্টগ্রেস্কল-এ (উইন্ডোতে 9.2.4 সংস্করণ) তারিখের মধ্যে তুলনা করার সময় আমি একটি অদ্ভুত দৃশ্যের মুখোমুখি হয়েছি। আমার টেবিলে একটি কলাম রয়েছে 'টাইমস্টোন ছাড়াই টাইমস্ট্যাম্প' টাইপ সহ আপডেট_ডেট say ক্লায়েন্ট কেবলমাত্র তারিখ (যেমন: 2013-05-03) বা সময়ের সাথে তারিখের সাথে এই ক্ষেত্রটি অনুসন্ধান করতে পারে (অর্থাত: 2013-05-03 12:20:00)। এই কলামটিতে বর্তমানে সমস্ত সারিগুলির টাইমস্ট্যাম্পের মান রয়েছে এবং একই তারিখের অংশ রয়েছে (2013-05-03) তবে সময়ের অংশে পার্থক্য রয়েছে।

আমি যখন এই কলামটির সাথে তুলনা করছি তখন আমি বিভিন্ন ফলাফল পাচ্ছি। নিম্নলিখিতগুলি পছন্দ করুন:

select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-03' -> No results

select * from table where update_date >= '2013-05-03' AND update_date < '2013-05-03' -> No results

select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-04' -> results found

select * from table where update_date >= '2013-05-03' -> results found

আমার প্রশ্ন হল আমি কীভাবে প্রথম ফলাফল অর্জনের সম্ভাব্যতা তৈরি করতে পারি, আমি কেন তৃতীয় কোয়েরিটি কাজ করছে তবে প্রথমটি নয়?

কেহ এই আমাকে সাহায্য করতে পারেন? আগাম ধন্যবাদ.

উত্তর:


274

@ নিকোলাই কাস্টিং সম্পর্কে সঠিক এবং কেন কোনও ডেটার জন্য শর্তটি মিথ্যা। আমার ধারণা আপনি প্রথম ফর্মটি পছন্দ করেন কারণ আপনি ইনপুট স্ট্রিংয়ের তারিখের কারসাজি এড়াতে চান, তাই না? আপনাকে ভয় পাওয়ার দরকার নেই:

SELECT *
FROM table
WHERE update_date >= '2013-05-03'::date
AND update_date < ('2013-05-03'::date + '1 day'::interval);

এই বাক্য গঠন ( '2013-05-03'::dateএবং '1 day'::interval) পোস্টগ্র্যাস এসকিউএল নির্দিষ্ট?
হিমশীতল শিখা

5
@ ফ্রোজেনফ্লেম হ্যাঁ এটি। মানক সিনট্যাক্সটি হবে CAST('2013-05-03' AS DATE) + CAST('1 day' AS INTERVAL)(আইআইআরসি)। অস্তিত্ব ও এর আচরণের উপর YMMV DATEএবং INTERVAL
ঠিক কেউ

@ ফ্রোজেনফ্লেম সঠিক, তারিখের ধরণের স্ট্রিং না ফেলে উত্তরটি কার্যকর হয় না। একটি কাস্ট এখনও অনুপস্থিত। সেখানে একটি করা প্রয়োজন ::DATEযেখানে দফা প্রথম অংশ যোগ করা
StillLearningToCode

WHERE update_date::date = '2013-05-03' পাশাপাশি কাজ করবে না এবং আরও কিছুটা পাঠযোগ্য?
মাইকএফ

@MikeF ওপি বলেন update_dateছিল timestamp without timezone। আমি column কলামটিতে একটি সূচক ধরেছি। আপনার প্রিডিকেট সেই সূচকটি ব্যবহার করবে না।
কেবলমাত্র

45

যখন আপনি update_date >= '2013-05-03'পোস্টগ্র্রেসকে মূল্যগুলি একই মানের সাথে তুলনা করতে মূল্যগুলি তুলনা করেন। সুতরাং আপনার '2013-05-03' '2013-05-03 00:00:00' তে কাস্ট করা হয়েছিল।

সুতরাং আপডেট_ডেটের জন্য = '2013-05-03 14:45:00' আপনার এক্সপ্রেশনটি হ'ল:

'2013-05-03 14:45:00' >= '2013-05-03 00:00:00' AND '2013-05-03 14:45:00' <= '2013-05-03 00:00:00'

এটি সর্বদা false

এই সমস্যার সমাধানের জন্য আপডেট_ তারিখটি কাস্ট করুন date:

select * from table where update_date::date >= '2013-05-03' AND update_date::date <= '2013-05-03' -> Will return result

1
update_dateটেবিলের প্রত্যেকটিতে কাস্টিং প্যারামিটারের একক মান ingালাই মারাত্মকভাবে অক্ষম, এবং এটি নিশ্চিত করে যে সার্ভারটি সেই কলামে সূচকগুলি উত্সাহিত করতে সক্ষম হবে না makes আমি এই -1 প্রলোভন করছি।
কেবলমাত্র

3
হ্যাঁ, আমি একমত যে প্রতিটি মানের ofালাই অদক্ষ এবং আপনি এই সমাধানের জন্য -1 দিতে পারেন। তবে আমি সমস্যার কারণ বর্ণনা করেছি এবং উদাহরণ দিয়েছি যা সমস্যাটি দেখায়। এখন ব্যবহারকারী 2866264 জানে কেন তার ক্যোয়ারী প্রত্যাশিত সারিগুলি ফেরত না এবং তার অনন্য মামলার জন্য ঠিক কী সমাধানটি আরও ভাল তা স্থির করবে solution
নিকোলাই

@ নিকোলাই: আপনার উত্তরের জন্য অনেক ধন্যবাদ। এটি আপনার উত্তর অনুসরণ করে কাজ করে। ব্যাখ্যার জন্য ধন্যবাদ।
ব্যবহারকারী 2866264

1
@ নিকোলাই - পোস্টগ্র্রেসটি মধ্যরাতের স্ট্রোকের তারিখকে আক্ষরিক আকারে প্রসারিত করার বিষয়ে আপনি যা বলেছিলেন তা প্রদত্ত, যদি লক্ষ্যটি একটি একক তারিখে চিহ্নিত করা হয় (3 শে মে), এই কোডটি সঠিক এবং আরও কার্যকর হবে: SELECT * FROM my_table WHERE update_date >= '2013-05-03' AND update_date < '2013-05-04'; (মে 4 র ব্যবহারের নোট করুন তৃতীয়টির চেয়ে কম এবং সমান বা তার চেয়ে কম স্বাক্ষরের সাথে স্বাক্ষর করুন))
বাসিল বাউরক

9

ব্যবহার rangeপ্রকারটি । যদি ব্যবহারকারী একটি তারিখ প্রবেশ করে:

select *
from table
where
    update_date
    <@
    tsrange('2013-05-03', '2013-05-03'::date + 1, '[)');

যদি ব্যবহারকারী টাইমস্ট্যাম্পগুলিতে প্রবেশ করে তবে আপনার ::date + 1অংশটির দরকার নেই

http://www.postgresql.org/docs/9.2/static/rangetypes.html

http://www.postgresql.org/docs/9.2/static/functions-range.html


এটি একটি সংক্ষিপ্ত এবং আকর্ষণীয় উত্তর!

2

তারিখের সাথে তুলনা করতে তারিখ রূপান্তর ব্যবহার করুন: এটি চেষ্টা করুন:

select * from table 
where TO_DATE(to_char(timespanColumn,'YYYY-MM-DD'),'YYYY-MM-DD') = to_timestamp('2018-03-26', 'YYYY-MM-DD')
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.