2012-03-15 10 views
20

मेरे पास पोस्टग्रेएसक्यूएल 8.4 के साथ एक सर्वर है जिसे हर रात 01:00 बजे (पूछना नहीं) पर रीबूट किया जा रहा है और कनेक्ट किए गए उपयोगकर्ताओं की सूची प्राप्त करने की आवश्यकता है (यानी उनके टाइमस्टैम्प u.login > u.logout हैं) :आज का चयन करें (मध्यरात्रि से) टाइमस्टैम्प केवल

SELECT u.login, u.id, u.first_name 
FROM pref_users u 
WHERE u.login > u.logout and 
     u.login > now() - interval '24 hour' 
ORDER BY u.login; 

      login   |   id | first_name 
----------------------------+----------------+------------- 
2012-03-14 09:27:33.41645 | OK171511218029 | Alice 
2012-03-14 09:51:46.387244 | OK448670789462 | Bob 
2012-03-14 09:52:36.738625 | OK5088512947 | Sergej 

लेकिन u.login > now()-interval '24 hour' की तुलना में भी पिछले 1:00 है, जो बुरा है, खास तौर पर पहले उन वितरित करता है। सुबह में।

कोई कारगर तरीका to_char() के साथ स्ट्रिंग कलाबाजी कर के बिना पिछले 1:00 के बाद से लॉगिन प्राप्त करने के लिए है?

+1

हायही, मुझे "पूछना नहीं है" :) – Mattis

उत्तर

30

@ फ्रैंक की टिप्पणी से प्रेरित मैंने कुछ परीक्षण चलाए और तदनुसार मेरी क्वेरी को अनुकूलित किया। यह 1) सही और 2) के रूप में तेजी से संभव के रूप में किया जाना चाहिए:

SELECT u.login, u.id, u.first_name 
FROM pref_users u 
WHERE u.login > u.logout 
AND u.login >= now()::date + interval '1h' 
ORDER BY u.login; 

अपनी तालिका में कोई भविष्य नहीं timestamps देखते हैं के रूप में (मुझे लगता है), तो आप कोई ऊपरी सीमा की जरूरत है।
date_trunc('day', now()) लगभग now()::date (या नीचे वर्णित कुछ अन्य विकल्प) जैसा ही है, केवल date के बजाय यह timestamp देता है। interval जोड़ने के बाद दोनों का परिणाम timestamp है।


अभिव्यक्तियों के नीचे थोड़ा अलग प्रदर्शन करते हैं। वे बहुत अलग परिणाम उत्पन्न करते हैं क्योंकि localtimestamp डेटा प्रकार timestamp देता है जबकि now()timestamp with time zone देता है। लेकिन जब date पर डाला जाता है, या तो उसी स्थानीय दिनांक में परिवर्तित किया जाता है, और timestamp [without time zone] स्थानीय समय क्षेत्र में भी माना जाता है। तो जब संबंधित timestamp with time zone की तुलना में वे सभी उसी यूटीसी टाइमस्टैम्प को आंतरिक रूप से परिणाम देते हैं। this related question में समय क्षेत्र हैंडलिंग पर अधिक जानकारी।

पांच में से सर्वश्रेष्ठ। PostgreSQL 9.0 के साथ परीक्षण किया। 9.1.5 के साथ दोहराया गया: लगातार परिणाम 1% त्रुटि मार्जिन के भीतर।

SELECT localtimestamp::date  + interval '1h' -- Total runtime: 351.688 ms 
    , current_date    + interval '1h' -- Total runtime: 338.975 ms 
    , date_trunc('day', now()) + interval '1h' -- Total runtime: 333.032 ms 
    , now()::date    + interval '1h' -- Total runtime: 278.269 ms 
FROM generate_series (1, 100000) 

now()::date जाहिर CURRENT_DATE की तुलना में थोड़ा तेज है।

+0

धन्यवाद। क्या तिथि से लेकर टाइमस्टैम्प लागत में कोई कलाकार है? –

+0

@AlexanderFarber: बेशक यह करता है - यहां तक ​​कि अगर बहुत कम है। –

+0

@Ewinwin Brandstetter: लेकिन 'date_trunc ('day', अब()) 'और भी अधिक खर्च हो सकता है, आपको नहीं लगता? –

3
where 
    u.login > u.logout 
    and  
    date_trunc('day', u.login) = date_trunc('day', now()) 
    and 
    date_trunc('hour', u.login) >= 1 
9

01:00 के बाद से वर्तमान दिन के लिए केवल समय टिकटों होने का एक आसान तरीका है तो आपकी क्वेरी इस तरह दिखना चाहिए CURRENT_DATE + interval '1 hour'

साथ फिल्टर करने के लिए है:

SELECT u.login, u.id, u.first_name 
FROM pref_users u 
WHERE u.login > u.logout AND 
     u.login > CURRENT_DATE + interval '1 hour' 
ORDER BY u.login; 

आशा है कि मदद करता है.

3
select * from termin where DATE(dateTimeField) >= CURRENT_DATE AND DATE(dateTimeField) < CURRENT_DATE + INTERVAL '1 DAY' 

यह मेरे लिए काम करता है - यह आज की तारीख के साथ सभी पंक्तियों का चयन करता है।

4
select * from termin where DATE(dateTimeField) = '2015-11-17' 

यह मेरे लिए अच्छा काम करता है!

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^