MySQLで月と年でグループ化


95

各行にタイムスタンプが設定されたテーブルがある場合、この特定のjsonオブジェクト形式に合うようにクエリをどのようにフォーマットしますか。

私はjsonオブジェクトを年/月に整理しようとしています。

クエリのベースとなるjson:

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

これが私が今までに持っているクエリです-

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

クエリは、(予想通り)年ごとにまとめられているため、故障しています。

回答:


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

あなたが欲しいものです。


60
+1:DATE_FORMATを使用した別の代替DATE_FORMAT(t.summaryDateTime, '%Y-%m')
OMGポニー

3
さらに、DBにUNIXタイムスタンプがある場合、FROM_UNIXTIMEが必要ですDATE_FORMAT( FROM_UNIXTIME(t.summaryDateTime), '%Y-%m' )
Duncanmoo

@OMGPoniesに感謝します。構文を使用して、条件付きGROUP BYを実行できます。
ヘンリー

パフォーマンス... 300,000を超えるエントリがあるInnoDBテーブルでの(GROUP BY YEAR(date), MONTH(date) DESC;〜450ミリ秒)およびGROUP BY DATE_FORMAT(date,'%Y-%m')(〜850ミリ秒)のテストでは、前者(この質問に対するマークされた回答)が後者の半分の時間を費やしたことが示されました。
ow3n

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

StackOverflowへようこそ!これは古い質問で、すでに回答されています。より差し迫った質問にもご協力いただければ幸いです。あなたはここで良い答えを提供するためのヒントを見つけることができます。
Mifeet

上記の回答に対する私のコメントを参照してください...大きな風のテーブルでは、この方法には2倍の時間がかかります。
ow3n

9

私は好む

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

正しい順序を取得するには、年と月の両方にDESCを使用する必要があります。


7

これは古い質問であることはわかっていますが、DBレベルで月の名前が必要ない場合は、次のようにしてください。

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

EXTRACT関数のドキュメントを参照してください

あなたはおそらくこれがより良いパフォーマンスであることに気付くでしょう。そして、アプリケーション層でJSONオブジェクトを構築している場合、結果を実行しながらフォーマット/順序付けを行うことができます。

注意:MySQLのGROUP BY句にDESCを追加できることを知りませんでした。おそらく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
からの出力EXTRACT(YEAR_MONTH FROM summaryDateTime)は次の201901
Edgar Ortega

@EdgarOrtegaはい、アプリケーションロジックを使用して元の質問で目的のJSONオブジェクトを生成するにはそれで十分です。クエリ結果に対する何らかのループが既に発生していると仮定すると、私のアプローチは、DBから必要最小限の情報をできるだけ簡単かつ迅速に取得することを目指しています
Arth

1
そうです、それで十分でしょう。私のコメントは、その関数からの出力がどのようなものであるかを示すことだけでした。
Edgar Ortega

@EdgarOrtegaご心配なく、ありがとうございます。
Arth

2

あなたはこのようなことをしなければなりません

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

あなたもこれをします

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

年と月で注文します。今年と今月から12か月までずっと注文したいとしましょう


1

このようなEXTRACT関数を使用する

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

1

これが私のやり方です:

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

それでも、探している構造を正確に取得するには、外部スクリプトで処理する必要があります。

たとえば、PHPのexplodeを使用して月の名前のリストから配列を作成し、json_encode()を使用します


-2

使用する

GROUP BY year, month DESC";

の代わりに

GROUP BY MONTH(t.summaryDateTime) DESC";

GROUP BY MONTH(t.summaryDateTime)DESCは、何らかの理由で月を適切に順序付けていないようですが
Derek Adair
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.