আমার ক্যোয়ারী অনুসন্ধানের ডেটটাইম মেলে না কেন?


20
select * 
from A 
where posted_date >= '2015-07-27 00:00:00.000' 
  and posted_date  <= '2015-07-27 23:59:59.999'

তবে ফলাফলটিতে এমন একটি রেকর্ড রয়েছে যা আজ পোস্ট করেছে: 2015-07-28। আমার ডাটাবেস সার্ভারটি আমার দেশে নেই। সমস্যাটা কি ?

উত্তর:


16

যেহেতু আপনি datetimeডেটাটাইপ ব্যবহার করছেন তাই আপনার বুঝতে হবে যে বেকার সার্ভারটি কীভাবে ডেটটাইম ডেটাকে বৃত্তাকার করে।

╔═══════════╦═════╦═════════════════════════════╦═════════════════════════════╦══════════╦═══════════╗
   Name     sn          Minimum value                Maximum value         Accuracy   Storage  
╠═══════════╬═════╬═════════════════════════════╬═════════════════════════════╬══════════╬═══════════╣
 datetime   dt   1753-01-01 00:00:00.000      9999-12-31 23:59:59.997      3.33 ms   8 bytes   
 datetime2  dt2  0001-01-01 00:00:00.0000000  9999-12-31 23:59:59.9999999  100ns     6-8 bytes 
╚═══════════╩═════╩═════════════════════════════╩═════════════════════════════╩══════════╩═══════════╝

এখানে চিত্র বর্ণনা লিখুন

কোয়েরির নীচে ব্যবহার করে, আপনি যখন DATETIMEডেটা টাইপ ব্যবহার করেন তখন স্কেল সার্ভারের গোল করার সমস্যাটি আপনি সহজেই দেখতে পাবেন ।

select  '2015-07-27 00:00:00.000'                       as Original_startDateTime,
        convert(datetime ,'2015-07-27 00:00:00.000')    as startDateTime,
        '2015-07-27 23:59:59.999'                       as Original_endDateTime,
        convert(datetime ,'2015-07-27 23:59:59.999')    as endDateTime,
        '2015-07-27 00:00:00.000'                       as Original_startDateTime2,
        convert(datetime2 ,'2015-07-27 00:00:00.000')   as startDateTime2,  -- default precision is 7
        '2015-07-27 23:59:59.999'                       as Original_endDateTime2,
        convert(datetime2 ,'2015-07-27 23:59:59.999')   as endDateTime2     -- default precision is 7

এখানে চিত্র বর্ণনা লিখুন সম্প্রসারিত করতে ক্লিক করুন

DATETIME2এসকিউএল সার্ভার ২০০৮ সাল থেকে প্রায় হয়েছে, সুতরাং এটির পরিবর্তে এটি ব্যবহার শুরু করুন DATETIME। আপনার পরিস্থিতির জন্য, আপনি উদাহরণস্বরূপ 3 ডেসিমালdatetime2 সহ ব্যবহার করতে পারেন ।datetime2(3)

ব্যবহারের সুবিধা datetime2:

  • বনাম সময় কম্পোনেন্ট 7 দশমিক স্থান পর্যন্ত সাপোর্ট datetimeমাত্র 3 দশমিক স্থান সমর্থনকারী .. তাই আপনাকে ডিফল্ট দ্বারা যেহেতু rounding সমস্যা দেখেছি datetimeনিকটতম .003 secondsবাড়তি সঙ্গে .000, .003বা .007সেকেন্ড।
  • datetime2চেয়ে অনেক বেশি সুনির্দিষ্ট datetimeএবং datetime2তোমাদের মধ্যে নিয়ন্ত্রণ দেয় DATEএবং TIMEযেমন উল্টোদিকে datetime

তথ্যসূত্র:


1
gives you control of DATE and TIME as opposed to datetime.ওটার মানে কি?
নুরেটিন

করছেন। DateTime2বনাম ব্যবহার করে DateTime: ক। - প্রকৃত - বিশ্বের - - - - এর বিশাল - সংখ্যাগরিষ্ঠ - ব্যবহার - ক্ষেত্রে, অনেক <ব্যয়ের সুবিধা । দেখুন: স্ট্যাকওভারফ্লো . com / প্রশ্নগুলি / 1334143/… খ। এটি এখানে মূল সমস্যা নয়। পরবর্তী মন্তব্য দেখুন। DateTime2
টম

এখানে মূল সমস্যাটি (আমি বেশিরভাগ বয়োজ্যেষ্ঠ দেবগণ সম্মত হবেন) হিসাবে কোনও তারিখের সময়সীমা তুলনার অন্তর্ভুক্ত সমাপ্ত তারিখের সময়টিতে অপ্রতুলতা যথাযথতা নয়, বরং এক সময়কালের অন্তর্ভুক্তি (বনাম একচেটিয়া) ব্যবহার । এটি পাই হিসাবে সমতা যাচাইয়ের মতো, সর্বদা সম্ভাবনা থাকে যে # datetime3টির মধ্যে একটির>> বা <নির্ভুলতা (যেমন যদি 70 (বনাম 7) সংখ্যক নির্ভুলতা যুক্ত হয় তবে কী হয়?)। শ্রেষ্ঠ অনুশীলন যেখানে স্পষ্টতা ব্যাপার না, অর্থাত্ <একটি মান ব্যবহার করা শুরু আগামী দ্বিতীয়, মিনিট, ঘন্টা বা দিনের বনাম <= এর শেষ পূর্বে দ্বিতীয়, মিনিট, ঘন্টা বা দিনের।
টম

18

আপনার প্রশ্নের মন্তব্যে এবং অন্যান্য উত্তরে আরও অনেকে উল্লেখ করেছেন যেহেতু মূল ইস্যুটি এসকিউএল সার্ভার দ্বারা 2015-07-27 23:59:59.999গোল করা হচ্ছে 2015-07-28 00:00:00.000ডকুমেন্টেশন প্রতি জন্য DATETIME:

সময়সীমা - 00:00:00 থেকে 23: 59: 59.997 এর মধ্যে

নোট করুন যে সময় সীমা কখনই হতে পারে না.999 । ডকুমেন্টেশনের আরও নিচে এটি এসকিউএল সার্ভারটি সর্বনিম্ন উল্লেখযোগ্য অঙ্কের জন্য ব্যবহার করে এমন গোলাকার নিয়ম নির্দিষ্ট করে।

রাউন্ডিং বিধি প্রদর্শন ছক

লক্ষ্য করুন যে সর্বনিম্ন উল্লেখযোগ্য অঙ্কের তিনটি সম্ভাব্য মানের মধ্যে একটি থাকতে পারে: "0", "3", বা "7"।

এর জন্য বেশ কয়েকটি সমাধান / ওয়ার্কআরউন্ডস রয়েছে যা আপনি ব্যবহার করতে পারেন।

-- Option 1
SELECT 
    * 
FROM A 
WHERE posted_date >= '2015-07-27 00:00:00.000' 
  AND posted_date <  '2015-07-28 00:00:00.000' --Round up and remove equality

-- Option 2
SELECT 
    * 
FROM A 
WHERE posted_date >= '2015-07-27 00:00:00.000' 
  AND posted_date <=  '2015-07-27 23:59:59.997' --Round down and keep equality

-- Option 3
SELECT 
    * 
FROM A 
WHERE CAST(posted_date AS DATE) = '2015-07-27' -- Use different data type

-- Option 4
SELECT 
    * 
FROM A 
WHERE CONVERT(CHAR(8), DateColumn, 112) = '20150727' -- Cast to string stripping off time

-- Option 5
SELECT 
    * 
FROM A 
WHERE posted_date BETWEEN '2015-07-27 00:00:00.000' 
  AND '2015-07-27 23:59:59.997' --Use between

উপরে উপস্থাপন করা পাঁচটি বিকল্পের মধ্যে আমি বিকল্প 1 এবং 3 কেবলমাত্র কার্যকর বিকল্পগুলি বিবেচনা করব। তারা আপনার উদ্দেশ্যটি স্পষ্টভাবে জানায় এবং আপনি ডেটা ধরণের আপডেট করে থাকলে তা ভাঙবে না। আপনি যদি এসকিউএল সার্ভার 2008 বা আরও নতুন ব্যবহার করছেন তবে আমি মনে করি বিকল্প 3 আপনার পছন্দসই পদ্ধতির হওয়া উচিত। এটি বিশেষত সত্য যদি আপনি আপনার কলামের জন্য ডেটা টাইপটি DATETIMEকোনও DATEডেটা টাইপ থেকে পরিবর্তন করতে পারেন posted_date

অপশন 3 সম্পর্কে, কিছু সমস্যা সম্পর্কে খুব ভাল ব্যাখ্যা এখানে পাওয়া যাবে: কাস্ট টু ডেট ব্যয় করা যায় তবে এটি কী ভাল ধারণা?

আমি বিকল্প 2 এবং 5 পছন্দ করি না কারণ .997ভগ্নাংশের সেকেন্ডগুলি কেবল একটি অন্য যাদু নম্বর হতে চলেছে যা লোকেরা "সংশোধন" করতে চায়। আরও কিছু কারণে কেন BETWEENব্যাপকভাবে আলিঙ্গন করা হচ্ছে না আপনি এই পোস্টটি চেকআউট করতে চাইতে পারেন ।

আমি বিকল্প 4 পছন্দ করি না কারণ তুলনার উদ্দেশ্যে ডেটা ধরণের স্ট্রিংয়ে রূপান্তর করা আমার কাছে নোংরা লাগে feels এসকিউএল সার্ভারে এটি এড়ানোর আরও গুণগত কারণ হ'ল এটি সারগাবিলিটি ওরফে প্রভাব ফেলে যে আপনি কোনও সূচক সন্ধান করতে পারবেন না এবং এর ফলে ঘন ঘন দরিদ্র কর্মক্ষমতা দেখা দেয়।

সঠিক ভাবে এবং হাতল তারিখের ব্যাপ্তি প্রশ্নের কুপথ আরও তথ্যের জন্য চেকআউট পোস্টটি দ্বারা হারুন বারট্রান্ড

বিভাজিকা আপনি এবং আপনার মূল প্রশ্নের সাথে রাখা করতে সক্ষম হবে যদি আপনি আপনার আপনার পরিবর্তন কাঙ্ক্ষিত যেমন আচরণ করবে posted_dateA থেকে কলাম DATETIMEএকটি থেকে DATETIME2(3)। এটি সার্ভারে স্টোরেজ স্পেস সংরক্ষণ করবে, একই নির্ভুলতায় আপনাকে আরও যথার্থতা দেবে, আরও মান মেনে চলবে / বহনযোগ্য হবে এবং ভবিষ্যতে আপনার প্রয়োজনীয়তা পরিবর্তিত হলে আপনি সহজেই নির্ভুলতা / নির্ভুলতা সামঞ্জস্য করতে পারবেন। তবে আপনি যদি এসকিউএল সার্ভার 2008 বা আরও নতুন ব্যবহার করছেন তবে এটি কেবলমাত্র একটি বিকল্প।

কিছুটা ট্রিভিয়া হিসাবে 1/300দ্বিতীয় যথার্থতার সাথে স্ট্যাকওভারফ্লো উত্তরটির প্রতিDATETIME ইউনিক্সের হাত ধরে বলে মনে হচ্ছে । সিবেস যার ভাগ করা heritage তিহ্য রয়েছে তাদের ডেটা ধরণের ক্ষেত্রে দ্বিতীয় যথার্থতার অনুরূপ রয়েছে তবে তাদের সর্বনিম্ন উল্লেখযোগ্য সংখ্যাগুলি "0", "3" এবং "6" এর চেয়ে আলাদা একটি স্পর্শ। আমার মতে দ্বিতীয় এবং / অথবা 3.33ms যথার্থতা একটি দুর্ভাগ্যজনক স্থাপত্য সংক্রান্ত সিদ্ধান্ত যেহেতু এসকিউএল সার্ভারের ডেটা টাইপের জন্য 4 বাইট ব্লকটি সহজেই 1 এমএস নির্ভুলতা সমর্থন করতে পারে।1/300DATETIMETIME1/300DATETIME


হ্যাঁ, তবে মূল "মূল সমস্যা" বিকল্প 1 ব্যবহার করছে না (যেমন কোনও অন্তর্ভুক্ত (বনাম। একচেটিয়া) পরিসীমা সমাপ্তি মান ব্যবহার করা হচ্ছে যেখানে অতীত বা সম্ভাব্য ভবিষ্যতের ডেটা ধরণের যথার্থতা ফলাফলের উপর প্রভাব ফেলতে পারে)। এটি পাই হিসাবে সমতা যাচাই করার মতো, এটি সর্বদা সম্ভব একটি # টি>> বা <নির্ভুলতা (যদি না উভয়ই সর্বনিম্ন সাধারণ যথাযথতার পূর্ববর্তী হয়)। datetime370 (বনাম 7) সংক্ষিপ্ত সংখ্যার সাথে যুক্ত হলে কী হবে ? সর্বোত্তম অনুশীলন হ'ল এমন মান ব্যবহার করা যেখানে যথার্থতা বিবেচনা না করে, যেমন <পরের দ্বিতীয়, মিনিট, ঘন্টা বা দিন বনাম শুরু <= পূর্ববর্তী দ্বিতীয়, মিনিট, ঘন্টা বা দিনের শেষ।
টম

9

অন্তর্নিহিত রূপান্তর

আমার মনে হয়েছে পোস্টের তারিখের টাইপটি টাইমটাইম Date তবে অন্যদিকে টাইপটি টাইমটাইম, ডেটটাইম 2 বা জাস্ট টাইম কিনা তা বিবেচ্য নয় কারণ স্ট্রিং (বর্ণচর) সুস্পষ্টভাবে ডেটটাইমে রূপান্তরিত হবে।

ডেটটাইম 2 (বা সময়) হিসাবে ঘোষিত পোস্ট_ডেটের সাথে posted_date <= '2015-07-27 23:59:59.99999'যেখানে ক্লজ ব্যর্থ হয় কারণ 23:59:59.99999পর্যাপ্ত পরিমাণ একটি বৈধ ডেটটাইম 2 মান, এটি কোনও বৈধ ডেটটাইম মান নয়:

 Conversion failed when converting date and/or time from character string.

তারিখের জন্য সময়সীমা

ডেটটাইমের সময়সীমা 00: 00:00 থেকে 23: 59: 59.997 এর মধ্যে। অতএব 23: 59: 59.999 সীমার বাইরে এবং নিকটতম মানের কাছে গোল বা উপরে হতে হবে।

সঠিকতা

ডেটটাইম মানগুলি ছাড়াও .000, .003 বা .007 সেকেন্ডের ইনক্রিমেন্ট দ্বারা গোল হয়। (যেমন, 000, 003, 007, 010, 013, 017, 020, ..., 997)

2015-07-27 23:59:59.999এই সীমার মধ্যে থাকা মানটির ক্ষেত্রে এটি হয় না : 2015-07-27 23:59:59.997এবং 2015-07-28 0:00:00.000

এই ব্যাপ্তিটি নিকটতম পূর্ববর্তী এবং নিম্নলিখিত বিকল্পগুলির সাথে সামঞ্জস্য, উভয়ই .000, .003 বা .007 দিয়ে শেষ হয়।

গোল হচ্ছে নাকি নিচে ?

কারণ এটা কাছাকাছি 2015-07-28 0:00:00.000(+1 টি বনাম -2) চেয়ে 2015-07-27 23:59:59.997: স্ট্রিং বৃত্তাকার আপ এবং এই DATETIME মান হয়ে হয় 2015-07-28 0:00:00.000

2015-07-27 23:59:59.998(বা .৯৯৫, .৯৯6, .৯৯7, .৯৯৮) এর মতো একটি উচ্চতর সীমা সহ এটি সীমাবদ্ধ হয়ে যেত 2015-07-27 23:59:59.997এবং আপনার ক্যোয়ারী প্রত্যাশা অনুযায়ী কাজ করবে। তবে এটি একটি সমাধান না হয়ে কেবল একটি ভাগ্যবান মান হত।

ডেটটাইম 2 বা টাইম টাইপ

Datetime2 এবং সময় সময় রেঞ্জ হয় 00:00:00.0000000মাধ্যমে 23:59:59.9999999100ns একটি সঠিকতা (শেষের ডিজিটটি যখন 7 অঙ্ক স্পষ্টতা সঙ্গে ব্যবহার) সঙ্গে।

তবে একটি ডেটটাইম (3) রেঞ্জ ডেটটাইম রেঞ্জের মতো নয়:

  • তারিখ 0:0:00.000সময়23:59:59.997
  • তারিখ 2 0:0:00.000000000থেকে23:59:59.999

সমাধান

দিনের শেষে নীচের বা তার সমান যে তারিখগুলি মনে করেন তার চেয়ে পরের দিন নীচের তারিখগুলি অনুসন্ধান করা নিরাপদ। এটি মূলত কারণ আপনি জানেন যে পরের দিনটি সর্বদা 0: 00: 00.000 এ শুরু হয় তবে বিভিন্ন ডেটা ধরণের দিন শেষে একই সময় নাও থাকতে পারে:

Datetime `0:0:00.000` to `23:59:59.997`
Datetime2 `0:0:00.000000000` to `23:59:59.999-999-900`
Time2 `0:0:00.000000000` to `23:59:59.999-999-900`
  • < 2015-07-28 0:00:00.000আপনাকে একটি সঠিক ফলাফল দেবে এবং এটি সেরা বিকল্প
  • <= 2015-07-27 23:59:59.xxx যখন আপনি যা ভাবেন এটি হওয়া উচিত নয় তখন এটি অপ্রত্যাশিত মানগুলি ফিরিয়ে দিতে পারে।
  • তারিখের রূপান্তর এবং ফাংশনের ব্যবহার এড়ানো উচিত কারণ এটি সূচকগুলির ব্যবহারকে সীমাবদ্ধ করে

আমরা ভাবতে পারি যে [পোস্ট_ডেট] ডেটটাইম 2 এ পরিবর্তন করা এবং এর উচ্চতর নির্ভুলতা এই সমস্যার সমাধান করতে পারে তবে এটি কোনও সহায়ক হবে না কারণ স্ট্রিংটি এখনও ডেটটাইমে রূপান্তরিত। তবে, যদি কোনও কাস্ট যুক্ত করা হয় তবে cast(2015-07-27 23:59:59.999' as datetime2)এটি দুর্দান্ত কাজ করে

কাস্ট এবং রূপান্তর

Castালাই 3 টি সংখ্যার সাথে ডেটটাইম বা 9 টি সংখ্যার সাথে ডেটটাইম 2 বা টাইমে রূপান্তর করতে পারে এবং এটিকে সঠিক নির্ভুলতায় পরিণত করতে পারে।

উল্লেখ্য যে ডেটটাইম 2 এবং টাইম 2 এর কাস্ট বিভিন্ন ফলাফল দিতে পারে:

  • select cast('20150101 23:59:59.999999999' as datetime2(7)) 2015-05-03 00: 00: 00.0000000 (999999949 এর চেয়ে বেশি মানের জন্য) গোলাকার
  • select cast('23:59:59.999999999' as time(7)) => 23: 59: 59.9999999

সমস্যা সমাধানের সময়সীমাটি 0, 3 এবং 7 বর্ধনের সাথে রয়েছে যদিও পরের দিন 1 ম ন্যানো দ্বিতীয় (সর্বদা 0: 00: 00.000) এর আগে তারিখগুলি সন্ধান করা আরও ভাল although

উত্স এমএসডিএন: ডেটটাইম (লেনদেন-এসকিউএল)


6

এটি গোলাকার হয়

 select cast('2015-07-27 23:59:59.999' as datetime) 
 returns 2015-07-28 00:00:00.000

.998, .997, .996, .995 সমস্ত কাস্ট / রাউন্ডে .997

ব্যবহার করা উচিত

select * 
from A 
where posted_date >= '2015-07-27 00:00:00.000' 
  and posted_date <  '2015-07-28 00:00:00.000'

অথবা

where cast(posted_date as date) = '2015-07-27'

এই লিঙ্কটিতে যথাযথতা দেখুন
সর্বদা .000, .003, .007 হিসাবে প্রতিবেদন করা হয়েছে


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