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.

Jawaban:


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

adalah yang kamu inginkan.


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')

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";

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.


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;

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

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


1

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


1

gunakan fungsi EKSTRAK seperti ini

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

1

Inilah cara saya melakukannya:

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

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 ()


-2

Menggunakan

GROUP BY year, month DESC";

Dari pada

GROUP BY MONTH(t.summaryDateTime) DESC";

meskipun tampaknya GROUP BY MONTH (t.summaryDateTime) DESC tidak memesan bulan dengan benar karena alasan tertentu ...
Derek Adair
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.