Kelompokkan menurut bulan dan tahun di MySQL

99

Diberikan tabel dengan stempel waktu di setiap baris, bagaimana Anda akan memformat kueri agar sesuai dengan format objek json tertentu ini.

Saya mencoba mengatur objek json menjadi tahun / bulan.

json untuk mendasarkan kueri:

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

Inilah pertanyaan yang saya miliki sejauh ini -

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

Kueri tersebut rusak karena (dapat diprediksi) menggabungkan tahun-tahun yang berbeda.

Derek Adair
sumber

Jawaban:

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

adalah yang kamu inginkan.

Mitch Dempsey
sumber
63
+1: Alternatif lain menggunakan DATE_FORMAT :DATE_FORMAT(t.summaryDateTime, '%Y-%m')
OMG Ponies
3
Lebih lanjut tentang ini, FROM_UNIXTIME diperlukan jika Anda memiliki stempel waktu UNIX di DB AndaDATE_FORMAT( FROM_UNIXTIME(t.summaryDateTime), '%Y-%m' )
Duncanmoo
Terima kasih @OMGPonies, dengan sintaks Anda saya dapat melakukan GROUP BY bersyarat.
Henry
Kinerja ... pengujian saya GROUP BY YEAR(date), MONTH(date) DESC;(~ 450 ms) dan GROUP BY DATE_FORMAT(date,'%Y-%m')(~ 850 ms) pada tabel InnoDB dengan> 300.000 entri menunjukkan yang pertama (jawaban yang ditandai untuk pertanyaan ini) membutuhkan waktu ~ separuh dari yang terakhir.
ow3n
78
GROUP BY DATE_FORMAT(summaryDateTime,'%Y-%m')
Ferhat KOÇER
sumber
Selamat datang di StackOverflow! Ini adalah pertanyaan lama dan sudah terjawab. Kami akan senang jika Anda dapat berkontribusi untuk pertanyaan yang lebih mendesak juga. Anda dapat menemukan tip untuk memberikan jawaban yang baik di sini .
Mifeet
Lihat komentar saya pada jawaban di atas ... Pada tabel besar, metode ini membutuhkan waktu dua kali lebih lama.
ow3n
9

aku lebih memilih

SELECT
    MONTHNAME(t.summaryDateTime) as month, YEAR(t.summaryDateTime) as year
FROM
    trading_summary t 
GROUP BY EXTRACT(YEAR_MONTH FROM t.summaryDateTime) DESC";
John McDonnell
sumber
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

Harus menggunakan DESC untuk YEAR dan Month untuk mendapatkan pesanan yang benar.

Sasindu H
sumber
7

Saya tahu ini adalah pertanyaan lama, tetapi yang berikut harus berfungsi jika Anda tidak memerlukan nama bulan di tingkat DB:

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

Lihat dokumen fungsi EXTRACT

Anda mungkin akan menganggap ini berkinerja lebih baik .. dan jika Anda membuat objek JSON di lapisan aplikasi, Anda dapat melakukan pemformatan / pengurutan saat Anda menjalankan hasil.

NB Saya tidak tahu Anda dapat menambahkan DESC ke klausa GROUP BY di MySQL, mungkin Anda kehilangan klausa ORDER BY:

  SELECT EXTRACT(YEAR_MONTH FROM summaryDateTime) summary_year_month 
    FROM trading_summary  
GROUP BY summary_year_month
ORDER BY summary_year_month DESC;
Arth
sumber
1
harap dicatat bahwa output dari EXTRACT(YEAR_MONTH FROM summaryDateTime)adalah201901
Edgar Ortega
@EdgarOrtega Ya, tetapi itu seharusnya cukup untuk menghasilkan objek JSON yang diinginkan dalam pertanyaan asli menggunakan logika aplikasi. Dengan asumsi bahwa beberapa bentuk perulangan atas hasil kueri sudah terjadi, pendekatan saya bertujuan untuk mendapatkan informasi minimum yang diperlukan dari DB sesederhana dan secepat mungkin
Arth
1
Anda benar, itu sudah cukup. Komentar saya hanya untuk menunjukkan seperti apa output dari fungsi itu, mungkin seseorang tidak menyukai format itu.
Edgar Ortega
@EdgarOrtega Jangan khawatir, terima kasih, kontribusi yang berharga!
Arth
2

Anda harus melakukan sesuatu seperti ini

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
michal
sumber
2

Anda juga bisa melakukan ini

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

untuk memesan berdasarkan tahun dan bulan. Katakanlah Anda ingin memesan mulai tahun ini dan bulan ini kembali ke bulan 12

Niclausel
sumber
1

Anda mengelompokkan berdasarkan bulan saja, Anda harus menambahkan YEAR () ke grup dengan

Eduardo Rascon
sumber
1

gunakan fungsi EKSTRAK seperti ini

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

Inilah cara saya melakukannya:

GROUP BY  EXTRACT(YEAR_MONTH FROM t.summaryDateTime);
CTBrewski
sumber
0
SELECT YEAR(t.summaryDateTime) as yr, GROUP_CONCAT(MONTHNAME(t.summaryDateTime)) AS month 
FROM trading_summary t GROUP BY yr

Anda tetap perlu memprosesnya dalam skrip eksternal untuk mendapatkan struktur yang Anda cari.

Misalnya gunakan ledakan PHP untuk membuat array dari daftar nama bulan dan kemudian gunakan json_encode ()

Mchl
sumber
-2

Menggunakan

GROUP BY year, month DESC";

Dari pada

GROUP BY MONTH(t.summaryDateTime) DESC";
Kyra
sumber
meskipun tampaknya GROUP BY MONTH (t.summaryDateTime) DESC tidak memesan bulan dengan benar karena alasan tertentu ...
Derek Adair