उन पंक्तियों का चयन कैसे करें जिनके पास वर्तमान दिन का टाइमस्टैम्प है?


104

मैं डेटाबेस तालिका से केवल आज के रिकॉर्ड का चयन करने का प्रयास कर रहा हूं।

वर्तमान में मैं उपयोग करता हूं

SELECT * FROM `table` WHERE (`timestamp` > DATE_SUB(now(), INTERVAL 1 DAY));

लेकिन यह पिछले 24 घंटों के लिए परिणाम लेता है, और मुझे समय की अनदेखी करते हुए आज से केवल परिणामों का चयन करने की आवश्यकता है। मैं केवल तिथि के आधार पर परिणाम कैसे चुन सकता हूं?

जवाबों:


191

का उपयोग करें DATEऔरCURDATE()

SELECT * FROM `table` WHERE DATE(`timestamp`) = CURDATE()

मुझे लगता है कि DATE अभी भी INDEX का उपयोग कर रहा है

DEMO पर निष्पादन योजना देखें


अंतर देखें: SQL-Fiddle नोट 2 में क्वेरी = 25 को फ़िल्‍टर करें।
ypercube y

@ypercube ओह मुझे याद आया लेकिन मैं सोच रहा था कि अतिरिक्त पर मूल्य क्यों है Using where; Using index?
जॉन वू

1
सूचकांक का उपयोग पंक्तियों का चयन करने के लिए किया जाता है। लेकिन पूरे सूचकांक को स्कैन किया जाता है (और सभी मान आपकी स्थिति के साथ DATE () की स्थिति का मूल्यांकन करने के लिए परिवर्तित किए जाते हैं)। मैं एक बेहतर उदाहरण के साथ अपने उत्तर को अपडेट करूंगा।
ypercube y

1
पूरे सम्मान के साथ, प्रदर्शन के कारणों के लिए ypercube समाधान बेहतर है, यदि आपकी तालिका में सैकड़ों हजारों लाइनें हैं, तो आपको निश्चित रूप से इस दिशा में जाना चाहिए
विन्सेंट

1
`` महत्वपूर्ण हैं क्योंकि timestamp(और dateमेरे मामले में) एक MySQL आरक्षित शब्द है
विक्टर फरेरा

55

यदि आप एक इंडेक्स का उपयोग करना चाहते हैं और एक टेबल स्कैन नहीं करने के लिए क्वेरी:

WHERE timestamp >= CURDATE()
  AND timestamp < CURDATE() + INTERVAL 1 DAY

यह दिखाने के लिए कि यह वास्तविक निष्पादन योजनाओं पर क्या फर्क पड़ता है, हम एसक्यूएल-फिडल (एक अत्यंत सहायक साइट) के साथ परीक्षण करेंगे :

CREATE TABLE test                            --- simple table
    ( id INT NOT NULL AUTO_INCREMENT
    ,`timestamp` datetime                    --- index timestamp
    , data VARCHAR(100) NOT NULL 
          DEFAULT 'Sample data'
    , PRIMARY KEY (id)
    , INDEX t_IX (`timestamp`, id)
    ) ;

INSERT INTO test
    (`timestamp`)
VALUES
    ('2013-02-08 00:01:12'),
    ---                                      --- insert about 7k rows
    ('2013-02-08 20:01:12') ;

अब 2 संस्करणों की कोशिश करें।


संस्करण 1 के साथ DATE(timestamp) = ?

EXPLAIN
SELECT * FROM test 
WHERE DATE(timestamp) = CURDATE()            ---  using DATE(timestamp)
ORDER BY timestamp ;

के बारे में बताएं:

ID  SELECT_TYPE  TABLE  TYPE  POSSIBLE_KEYS  KEY  KEY_LEN  REF 
1   SIMPLE       test   ALL

ROWS  FILTERED  EXTRA
6671  100       Using where; Using filesort

यह सभी (6671) पंक्तियों को फ़िल्टर करता है और फिर एक फाइलशॉर्ट करता है (यह समस्या नहीं है क्योंकि लौटी पंक्तियाँ कुछ कम हैं)


संस्करण 2 के साथ timestamp <= ? AND timestamp < ?

EXPLAIN
SELECT * FROM test 
WHERE timestamp >= CURDATE()
  AND timestamp < CURDATE() + INTERVAL 1 DAY
ORDER BY timestamp ;

के बारे में बताएं:

ID  SELECT_TYPE  TABLE  TYPE  POSSIBLE_KEYS  KEY  KEY_LEN  REF 
1   SIMPLE       test   range t_IX           t_IX    9 

ROWS  FILTERED  EXTRA
2     100       Using where

यह इंडेक्स पर एक रेंज स्कैन का उपयोग करता है , और फिर तालिका से केवल संबंधित पंक्तियों को पढ़ता है।


sql-fiddle के लिए महान स्पष्टीकरण और धन्यवाद। आपके स्कीमा पर एक टिप्पणी जिसने मुझे एक पल के लिए फेंक दिया, वह INDEX t_IX (timestamp, id)हो सकता है (चाहिए?) INDEX t_IX (timestamp), जैसा कि प्राथमिक कुंजी सूचकांक में निहित है। या वहाँ एक कारण है कि मैं ऐसा करने के लिए समझ में नहीं आता है? मैंने इसे sql-fiddle में आज़माया और उसी (बेहतर) निष्पादन योजना को देखा
natbro

1
@natbro हाँ, यदि तालिका InnoDB इंजन का उपयोग करती है, id(क्योंकि यह PK है और इस प्रकार तालिका का क्लस्टर इंडेक्स) वैसे भी सूचकांक में संलग्न है। तो, यह स्पष्ट रूप से इसे जोड़ने के लिए चोट नहीं करता है (और यह कुछ ऑप्टिमाइज़र अंधा धब्बों को पकड़ सकता है)। यह निश्चित रूप से इस मामले / क्वेरी में प्रासंगिक नहीं है।
ypercube y

क्या कोई समझा सकता है कि क्यों timestamp < CURDATE() + INTERVAL 1 DAYजरूरी है?
नाइटवॉल्फ

@ नाइटवॉल्फ क्योंकि आपके पास पंक्तियां हो सकती हैं जहां भविष्य में टाइमस्टैम्प का मूल्य है। सवाल "केवल आज के रिकॉर्ड" के लिए पूछता है ।
ypercube y

@ TypoCube Typ अहा, उस विशुद्ध रूप से विचार नहीं किया क्योंकि टाइमस्टैम्प भविष्य की तारीखों को नहीं करेगा। फिर भी ध्यान रखने योग्य अच्छी बात है।
नाइटवॉल्फ

11
SELECT * FROM `table` WHERE timestamp >= CURDATE()

यह छोटा है, 'AND timestamp <CURDATE () + INTERVAL 1 DAY' का उपयोग करने की कोई आवश्यकता नहीं है

क्योंकि CURDATE () हमेशा चालू दिन लौटता है

MySQL CURDATE () फ़ंक्शन


क) प्रश्न "केवल आज के रिकॉर्ड" के लिए पूछता है, और आपके कोड को भविष्य की तारीखें भी मिलती हैं। b) आपकी तुलना काम नहीं करती है, आपको इसे DATE (टाइमस्टैम्प) के साथ करना होगा दूसरे शब्दों में: यदि आप अपना उत्तर ठीक करते हैं, तो आपको @JohnWoo मूल उत्तर प्राप्त होगा।
काटाफॉफैटो

2

हम इस बिल्ली को कितने तरीके से चमका सकते हैं? यहाँ अभी एक और संस्करण है।

tableजहां से चयन करें * (FROM_UNIXTIME ( timestamp)) = '2015-11-18';


2

यदि आप किसी विशेष तिथि से तुलना करना चाहते हैं, तो आप इसे सीधे लिख सकते हैं जैसे:

select * from `table_name` where timestamp >= '2018-07-07';

// यहां टाइमस्टैम्प उस कॉलम का नाम है जिसमें टाइमस्टैम्प टाइप है

या

आज की तारीख में लाने के लिए, CURDATE () फ़ंक्शन उपलब्ध है, इसलिए:

select * from `table_name` where timestamp >=  CURDATE();

1

बस इसे तारीख पर कास्ट करें:

SELECT * FROM `table` WHERE CAST(`timestamp` TO DATE) == CAST(NOW() TO DATE)



0

विजुअल स्टूडियो 2017 में, विकास के लिए अंतर्निहित डेटाबेस का उपयोग करके मुझे वर्तमान दिए गए समाधान के साथ समस्या थी, मुझे इसे काम करने के लिए कोड को बदलना पड़ा क्योंकि इसने त्रुटि को फेंक दिया कि DATE () फ़ंक्शन में निर्मित नहीं था।

यहाँ मेरा समाधान है:

where CAST(TimeCalled AS DATE) = CAST(GETDATE() AS DATE)


आप शायद MySQL का उपयोग नहीं कर रहे थे लेकिन कुछ अन्य DBMS (SQL सर्वर शायद?) प्रश्न के टैग को नोटिस करते हैं।
ypercube y
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.