MySQL'de ay ve yıla göre gruplama


102

Her satırda bir zaman damgası olan bir tablo verildiğinde, sorguyu bu belirli json nesne biçimine sığacak şekilde nasıl biçimlendirirsiniz?

Bir json nesnesini yıllar / aylar halinde düzenlemeye çalışıyorum.

json sorguyu temel almak için:

{
  "2009":["August","July","September"],
  "2010":["January", "February", "October"]
}

İşte şimdiye kadar sahip olduğum sorgu -

SELECT
    MONTHNAME(t.summaryDateTime) as month, YEAR(t.summaryDateTime) as year
FROM
    trading_summary t 
GROUP BY MONTH(t.summaryDateTime) DESC";

Sorgu çöküyor çünkü (tahmin edilebileceği üzere) farklı yılları bir araya getiriyor.

Yanıtlar:


191
GROUP BY YEAR(t.summaryDateTime), MONTH(t.summaryDateTime) DESC;

istediğin şey.


64
+1: DATE_FORMAT kullanan başka bir alternatif :DATE_FORMAT(t.summaryDateTime, '%Y-%m')
OMG Ponies

3
Ayrıca bu konuda, FROM_UNIXTIME size DB UNIX zaman damgası varsa gereklidirDATE_FORMAT( FROM_UNIXTIME(t.summaryDateTime), '%Y-%m' )
Duncanmoo

Teşekkürler @OMGPonies, sözdiziminizle koşullu GROUP BY gerçekleştirebiliyorum.
Henry

Performans ... InnoDB tablosunda> 300.000 girişli GROUP BY YEAR(date), MONTH(date) DESC;(~ 450 ms) ve GROUP BY DATE_FORMAT(date,'%Y-%m')(~ 850 ms) testim, ilkinin (bu sorunun işaretli cevabı) ikincisinin yaklaşık yarısı kadar zaman aldığını gösterdi.
ow3n

78
GROUP BY DATE_FORMAT(summaryDateTime,'%Y-%m')

StackOverflow'a hoş geldiniz! Bu eski ve önceden cevaplanmış bir sorudur. Daha acil sorulara da katkıda bulunursanız mutlu oluruz. Burada iyi cevaplar vermeniz için ipuçları bulabilirsiniz .
Mifeet

Yukarıdaki cevapla ilgili yorumuma bakın ... Büyük boyutlu tablolarda bu yöntem iki kat daha uzun sürer.
ow3n

9

tercih ederim

SELECT
    MONTHNAME(t.summaryDateTime) as month, YEAR(t.summaryDateTime) as year
FROM
    trading_summary t 
GROUP BY EXTRACT(YEAR_MONTH FROM t.summaryDateTime) DESC";

8
SELECT MONTHNAME(t.summaryDateTime) as month, YEAR(t.summaryDateTime) as year
FROM trading_summary t
GROUP BY YEAR(t.summaryDateTime) DESC, MONTH(t.summaryDateTime) DESC

Doğru sipariş almak için hem YIL hem de Ay için DESC kullanmalısınız.


7

Bunun eski bir soru olduğunu biliyorum, ancak DB düzeyinde ay adına ihtiyacınız yoksa aşağıdakiler işe yarayacaktır:

  SELECT EXTRACT(YEAR_MONTH FROM summaryDateTime) summary_year_month 
    FROM trading_summary  
GROUP BY summary_year_month;

EXTRACT işlevi belgelerine bakın

Muhtemelen bunun daha iyi performans gösterdiğini göreceksiniz .. ve uygulama katmanında bir JSON nesnesi oluşturuyorsanız, sonuçlarda ilerlerken biçimlendirme / sıralamayı yapabilirsiniz.

NB MySQL'deki bir GROUP BY yan tümcesine DESC ekleyebileceğinizi bilmiyordum, belki de ORDER BY yan tümcesini atlamışsınızdır:

  SELECT EXTRACT(YEAR_MONTH FROM summaryDateTime) summary_year_month 
    FROM trading_summary  
GROUP BY summary_year_month
ORDER BY summary_year_month DESC;

1
çıktısı unutmayın EXTRACT(YEAR_MONTH FROM summaryDateTime)olduğunu201901
Edgar Ortega

@EdgarOrtega Yep, ancak bu, uygulama mantığını kullanarak orijinal soruda istenen JSON nesnesini oluşturmak için yeterli olmalıdır. Sorgu sonucu üzerinde döngü çeşit zaten oluyor ki yaklaşımım amaçlarını varsayarsak mümkün olduğunca çabuk basitçe DB'den gerekli minimum bilgi almak ve
Arth

1
Haklısın, bu yeterli olmalı. Benim yorumum sadece bu fonksiyonun çıktısının neye benzediğini, belki birisi bu formattan hoşlanmadığını belirtmekti.
Edgar Ortega

@EdgarOrtega Endişelenmeyin, teşekkürler, değerli bir katkı!
Arth

2

Bunun gibi bir şey yapmalısın

SELECT onDay, id, 
sum(pxLow)/count(*),sum(pxLow),count(`*`),
CONCAT(YEAR(onDay),"-",MONTH(onDay)) as sdate 
FROM ... where stockParent_id =16120 group by sdate order by onDay

2

Bunu da yap

SELECT  SUM(amnt) `value`,DATE_FORMAT(dtrg,'%m-%y') AS label FROM rentpay GROUP BY YEAR(dtrg) DESC, MONTH(dtrg) DESC LIMIT 12

yıl ve aya göre sipariş vermek için. Diyelim ki bu yıldan ve bu aydan 12 aya kadar sipariş vermek istiyorsunuz



1

EXTRACT işlevini bunun gibi kullanın

mysql> SELECT EXTRACT(YEAR FROM '2009-07-02');
       -> 2009

1

Ben böyle yaparım:

GROUP BY  EXTRACT(YEAR_MONTH FROM t.summaryDateTime);

0
SELECT YEAR(t.summaryDateTime) as yr, GROUP_CONCAT(MONTHNAME(t.summaryDateTime)) AS month 
FROM trading_summary t GROUP BY yr

Yine de tam olarak aradığınız yapıyı elde etmek için harici komut dosyasında işlemeniz gerekir.

Örneğin, ay adları listesinden bir dizi oluşturmak için PHP'nin patlatmasını kullanın ve ardından json_encode () kullanın


-2

Kullanım

GROUP BY year, month DESC";

Onun yerine

GROUP BY MONTH(t.summaryDateTime) DESC";

o GRUBU TARAFINDAN AY (t.summaryDateTime) DESC nedense düzgün aylar sipariş bulunmadığını tespit ettik rağmen ...
Derek Adair
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.