2011-04-04 14 views
11

Son zamanlarda, PostgreSQL'i (8.2'yi kullanarak) aşina oldum ve date_trunc işlevinin, belirli günler/aylar/günler arasında zaman damgalarını kolayca eşleştirmek için son derece yararlı buldum. Fonksiyonun gerçek kullanışlılığı, çıktının bir zaman damgası biçiminde tutulması gerçeğinden kaynaklandığına inanıyorum.PostgreSQL'in date_trunc in mySQL

MySQL (5.0) 'e geçmek ve karşılaştırma yapmaktan ziyade bazı tarih işlevlerini bulmak zorunda kaldım. Ayıklama işlevi kullanışlı görünüyor ve bulduğum tarih işlevi bazı sorunlarımı çözüyor, ancak PostgreSQL'in date_trunc'ını kopyalamanın herhangi bir yolu var mı?

WHERE date_trunc('month', QUERY_DATE) BETWEEN 
    date_trunc('month', now()) - INTERVAL '4 MONTH' AND 
    date_trunc('month', now() - INTERVAL '1 WEEK') 

I: Haftada zaten bu ay geçmiştir yalnızca

ardından ben geçerli ay dahil olmak üzere yalnızca son 4 aya sorgulanan damgaları maç için date_trunc kullanmak için kullanılan bir örnek olmakla birlikte, mySQL'de böyle bir şartın nasıl yeniden yaratılacağına dair hiçbir fikriniz yok. Yani, günün sonunda benim soru, bu tür bir sorgu işinizi yapmak için farklı bir şekilde bu tür sorgulara bakmaya başlamak ister mi, yoksa tarihini çoğaltmaya çalışarak mySQL'de gerçekleştirilip gerçekleştirilemeyeceğidir. mySQL'de (ve bunu nasıl yapacağınıza dair öneriler)?

cevap

21

Ayıklama işlevi kullanışlı görünüyor ve bulduğum tarih işlevi bazı sorunlarımı çözüyor, ancak PostgreSQL'in date_trunc'sini çoğaltmanın herhangi bir yolu var mı?

Gerçekten de, bu özel durum için en yakın eşleşme olacak gibi görünüyor. PG içinde

Orijinal kod:

WHERE date_trunc('month', QUERY_DATE) BETWEEN 
    date_trunc('month', now()) - INTERVAL '4 MONTH' AND 
    date_trunc('month', now() - INTERVAL '1 WEEK') 

EXTRACT kullanma: o işlevsel aynı olması gerekirken

WHERE EXTRACT(YEAR_MONTH FROM QUERY_DATE) 
     BETWEEN 
      EXTRACT(YEAR_MONTH FROM NOW() - INTERVAL 4 MONTH) 
     AND 
      EXTRACT(YEAR_MONTH FROM NOW() - INTERVAL 1 WEEK) 

, bu aslında karşılaştırma yapmadan önce YYYYAA dizesine tarihleri ​​bozma edilir.

Diğer bir seçenek tarih dizesi yeniden inşa etmek ve ay başında zorlamak DATE_FORMAT kullanarak olacaktır: MySQL tarih aralıkları ile uğraşan gerçekten kötü olduğunu da

WHERE DATE_FORMAT(QUERY_DATE, '%Y-%m-01') 
     BETWEEN 
      DATE_FORMAT(NOW() - INTERVAL 4 MONTH, '%Y-%m-01') 
     AND 
      DATE_FORMAT(NOW() - INTERVAL 1 WEEK, '%Y-%m-01') 

, farkında bile alan endekslendi. Dikkatli olmamanız muhtemelen bir masa başı taramasıyla sonuçlanacaksınız.

3
geç partiye

, ama ...

Eğer aralık biliyor verilen kesik tarihi almak için bir yolu yoktur. aralık MONTH ise Örneğin, bugünün tarihini (now()) alabilir aşağıdaki kullanarak aya kesildi: aynı zamanda diğer aralıklarla bakmak

select date_add('1900-01-01', interval TIMESTAMPDIFF(MONTH, '1900-01-01', now()) MONTH); 

yukarıda göz önüne alındığında, bir bir işlev oluşturabilir :

DELIMITER // 
create function date_trunc(vInterval varchar(7), vDate timestamp) 
returns timestamp 
begin 
    declare toReturn timestamp; 

    if vInterval = 'year' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(YEAR, '1900-01-01', vDate) YEAR); 
    elseif vInterval = 'quarter' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(QUARTER, '1900-01-01', vDate) QUARTER); 
    elseif vInterval = 'month' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(MONTH, '1900-01-01', vDate) MONTH); 
    elseif vInterval = 'week' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(WEEK, '1900-01-01', vDate) WEEK); 
    elseif vInterval = 'day' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(DAY, '1900-01-01', vDate) DAY); 
    elseif vInterval = 'hour' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(HOUR, '1900-01-01', vDate) HOUR); 
    elseif vInterval = 'minute' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(MINUTE, '1900-01-01', vDate) MINUTE); 
    END IF; 

    return toReturn; 
end// 
DELIMITER ; 

şöyle kullanın:

select date_trunc('quarter', now())