SQL "बीच" समावेशी नहीं है


136

मेरे पास इस तरह से एक प्रश्न है:

SELECT * FROM Cases WHERE created_at BETWEEN '2013-05-01' AND '2013-05-01'

लेकिन यह 1 पर डेटा होने के बावजूद कोई परिणाम नहीं देता है।

created_atलगता है 2013-05-01 22:25:19, मुझे संदेह है कि यह समय के साथ क्या करना है? इसे कैसे हल किया जा सकता है?

यदि मैं बड़ी तिथि सीमाएँ करता हूँ तो यह ठीक काम करता है, लेकिन इसे (समावेशी) एक ही तिथि के साथ भी काम करना चाहिए।


23
वैसे, 1 और 1 के बीच कितनी संख्याएँ हैं? क्या १ और १ के बीच १.५ होना चाहिए? बस दिनांक / समय सीमा के लिए बीटा का उपयोग न करें। कभी। और सावधान रहें कि आप "ठीक काम करता है" का मूल्यांकन कैसे करते हैं - क्या आपने पिछले दिन से सीमा में परिणामों का बारीकी से निरीक्षण किया है? यदि आपके पास उनसे जुड़ा कोई समय नहीं है, तो आप केवल सभी पंक्तियों को शामिल करेंगे।
एरॉन बर्ट्रेंड

हारून के लिए अपडेट किया गया URL: sqlblog.org/2011/10/19/…
JayRizzo

जवाबों:


296

यह है समावेशी। आप डेटसेट की तुलना डेट्स से कर रहे हैं। दूसरी तिथि की व्याख्या दिन शुरू होने पर आधी रात के रूप में की जाती है

इसे ठीक करने का एक तरीका है:

SELECT *
FROM Cases
WHERE cast(created_at as date) BETWEEN '2013-05-01' AND '2013-05-01'

इसे ठीक करने का एक और तरीका स्पष्ट बाइनरी तुलना के साथ है

SELECT *
FROM Cases
WHERE created_at >= '2013-05-01' AND created_at < '2013-05-02'

हारून बर्ट्रेंड की तारीखों ( यहां ) पर एक लंबी ब्लॉग प्रविष्टि है , जहां वह इस और अन्य तारीख के मुद्दों पर चर्चा करते हैं।


15
इस अच्छे उत्तर के लिए पूर्णता के लिए, मैं dateaddअगले दिन प्राप्त करने के लिए उपयोग करने का सुझाव दूंगा ।
टिम लेहनर

7
@TimLehner एक अच्छे उत्तर के लिए, मैंने '20130501' के ISO-8601 प्रारूप का उपयोग किया होगा। गैर-अमेरिकी लोगों के लिए डेटफ़ॉर्मेट डमी के साथ, आपको यह मिलता है:set dateformat dmy;select month(cast('2013-05-01' as datetime)); =1
रिचर्ड दाइवी

2
@RichardTheKiwi - मेरा मानना ​​है कि स्पष्ट बिट एक अंत में बंद अंतराल का उपयोग कर रहा है ( >=) और दूसरे पर खुला ( <) निर्दिष्ट समाप्ति तिथि से एक दिन पहले जाँच के साथ संयुक्त है।
HABO

3
@ व्यक्तिगत रूप से, मुझे लगता है कि हर बार जब मैं प्रदर्शन, निर्यात, आयात, या एक डेटाइम के साथ एक वर्ग लिखना चाहता था, तो मुझे डेटासेट में कनवर्ट करने के लिए परेशान होना पड़ेगा। मुझे लगता है कि SQL सर्वर में अधिकांश उद्देश्यों के लिए डेटाटाइम्स को हेरफेर करने और तुलना करने के लिए बहुत सारी अंतर्निहित कार्यक्षमता है।
टिम लेहनर

10
आपको whereक्लॉज में कभी कॉलम नहीं डालना चाहिए , क्योंकि इससे कोई भी इंडेक्सिंग खो जाएगी। यह वास्तव में खराब पैटर्न है।
बुजिनास

49

यह माना गया है कि BETWEENवाक्य रचना में दूसरी तारीख के संदर्भ को जादुई रूप से "दिन का अंत" माना जाता है लेकिन यह असत्य है

यानी यह अपेक्षित था:

मामलों से चयन करें * 
जहां के बीच created_at की शुरुआत '2013-05-01' और के अंत '2013-05-01'

लेकिन वास्तव में क्या होता है:

मामलों से चयन करें * 
WHAT ने बनाया_टाउन '2013-05-01 00: 00: 00 + 00000 ' और '2013-05-01 00: 00: 00 + 00000 '

जो इसके बराबर हो जाता है:

सेलेक्ट करें * से जहां से बनाया गया है वहाँ = '2013-05-01 00: 00: 00 + 00000 '

समस्या धारणाओं / अपेक्षाओं के बारे में से एक है BETWEENजो करता है दोनों कम मूल्य और रेंज में ऊपरी मूल्यों शामिल हैं, लेकिन यह नहीं है जादुई बनाने के लिए एक तिथि या "के अंत" "की शुरुआत"।

BETWEEN तिथि सीमा के अनुसार छानने से बचना चाहिए।

>= AND <इसके बजाय हमेशा उपयोग करें

मामलों से चयन करें * 
कहाँ (बनाया_त > = '20130501' और बनाया_त < '20130502')

कोष्ठक यहाँ वैकल्पिक हैं, लेकिन अधिक जटिल प्रश्नों में महत्वपूर्ण हो सकते हैं।


2
प्रश्न के उत्तर के बाद इसे अच्छी तरह से पोस्ट करने की बुद्धिमत्ता के बारे में अनिश्चित, लेकिन मैं थोड़ा अलग बिंदु पर जोर देना चाहता था
Used_By_Already

5
संपादकों को; कृपया कोड ब्लॉक में छद्म एसक्यूएल बनाने की कोशिश न करें, यह बस काम नहीं करता है क्योंकि टिप्पणी बोल्ड पर निर्भर करती है।
प्रयुक्त_By_Already

2
संपादकों (फिर से) के लिए, छद्म कोड के माध्यम से नकली उद्धरण चिह्न न जोड़ें; वे समझ की सहायता नहीं करते हैं।
Use_By_Already

18

आपको इन दो विकल्पों में से एक करने की आवश्यकता है:

  1. अपनी betweenस्थिति में समय घटक को शामिल करें : ... where created_at between '2013-05-01 00:00:00' and '2013-05-01 23:59:59'(अनुशंसित नहीं ... अंतिम पैराग्राफ देखें)
  2. के बजाय असमानताओं का उपयोग करें between। ध्यान दें कि फिर आपको एक दिन दूसरे मूल्य में जोड़ना होगा:... where (created_at >= '2013-05-01' and created_at < '2013-05-02')

मेरी व्यक्तिगत पसंद दूसरा विकल्प है। इसके अलावा, हारून बर्ट्रेंड का बहुत स्पष्ट स्पष्टीकरण है कि इसका उपयोग क्यों किया जाना चाहिए।


6
+1 के लिए 2. लेकिन -1 के लिए 1. दिन की हैक का यह अंत पूरी तरह से अविश्वसनीय और एक बुरा विचार है।
आरोन बर्ट्रेंड

1
@AaronBertrand मैं भी विकल्प 2 पसंद करता हूं (मैं इसे अक्सर उपयोग करता हूं)। लेकिन आप यह क्यों कहते हैं कि विकल्प 1 "पूरी तरह से अविश्वसनीय" है?
बैरनका

5
कृपया इसे पूरा पढ़ें । आपको कभी भी BETWEENसमय सीमा वाले दिनांक प्रश्नों का उपयोग नहीं करना चाहिए ; बहुत ज्यादा गलत हो सकता है
आरोन बर्ट्रेंड

7

बस समय की मोहर का उपयोग दिनांक के रूप में करें:

SELECT * FROM Cases WHERE date(created_at)='2013-05-01' 

4
प्रश्न SQL सर्वर को टैग किया गया है, और stackoverflow.com/a/20973452/4233593'DATE' is not a recognized built-in function name.
Jeff Puckett

7

मुझे लगता है कि डेटटाइम क्षेत्र की तुलना डेट फ़ील्ड से करने का सबसे अच्छा समाधान निम्नलिखित है:

DECLARE @StartDate DATE = '5/1/2013', 
        @EndDate   DATE = '5/1/2013' 

SELECT * 
FROM   cases 
WHERE  Datediff(day, created_at, @StartDate) <= 0 
       AND Datediff(day, created_at, @EndDate) >= 0 

यह कथन के बीच एक समावेशी के बराबर है क्योंकि इसमें प्रारंभ और समाप्ति तिथि के साथ-साथ बीच में आने वाले दोनों शामिल हैं।


3
cast(created_at as date)

यह केवल 2008 और SQL सर्वर के नए संस्करणों में काम करेगा

यदि आप पुराने संस्करण का उपयोग कर रहे हैं तो उपयोग करें

convert(varchar, created_at, 101)

2
convert(varchar, created_at, 101)परिणाम जैसा है dd/MM/yyyyऔर ओपी के तार हैं yyyy-MM-dd, मुझे लगता है कि यह जवाब काम नहीं करेगा;)।
shA.t

2

आप उस date()फ़ंक्शन का उपयोग कर सकते हैं जो डेटटाइम से तारीख निकालेगा और आपको समावेशी तिथि के रूप में परिणाम देगा:

SELECT * FROM Cases WHERE date(created_at)='2013-05-01' AND '2013-05-01'

0

डायनामिक डेट बीटा स्क्वल क्वेरी

var startDate = '2019-08-22';
var Enddate = '2019-10-22'
     let sql = "SELECT * FROM Cases WHERE created_at BETWEEN '?' AND '?'";
     const users = await mysql.query( sql, [startDate, Enddate]);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.