在 MySQL 中按月份和年份分组

给定一个每行都有时间戳的表,如何将查询格式化以适应这种特定的 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";

这个查询正在崩溃,因为它(可以预见)将不同的年份集中在一起。

181502 次浏览

使用

GROUP BY year, month DESC";

而不是

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

就是你想要的。

仅按月进行分组,则必须通过以下方式向组中添加 YEAR ()

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

不过,您仍然需要在外部脚本中处理它,以获得您正在寻找的结构。

例如,使用 PHP 爆炸从月名列表中创建一个数组,然后使用 json _ encode ()

你必须这么做

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
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。

像这样使用 EXTRACT 函数

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

我更喜欢

SELECT
MONTHNAME(t.summaryDateTime) as month, YEAR(t.summaryDateTime) as year
FROM
trading_summary t
GROUP BY EXTRACT(YEAR_MONTH FROM t.summaryDateTime);
GROUP BY DATE_FORMAT(summaryDateTime,'%Y-%m')

你打电话也这样做

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

按年份和月份订购。假设你想从今年和这个月一直订到12个月

我知道这是一个老问题,但以下应该工作,如果你不需要在数据库级别的月份名称:

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

参见 EXTRACT 函数文档

您可能会发现这种方法的性能更好。.如果在应用程序层中构建 JSON 对象,则可以在运行结果时执行格式化/排序。

N.B. 我不知道你可以在 MySQL 中将 DESC 添加到 GROUP BY 子句中,也许你漏掉了一个 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;

我是这么做的:

GROUP BY  EXTRACT(YEAR_MONTH FROM t.summaryDateTime);

我想添加按年(datetime)、按月(datetime)和按提取(year _ month from datetime)分组的差异。 这是我在这两个案例中的疑问。

从表中选择 Year (datetimecol)作为 Year,monthname (datetimecol)作为 Month
按年(datetimecol)分组,按月(datetimecol)按年(datetimecol)下订单;

结果:

年、月

2020年5月

从表中选择 Year (datetimecol)作为 Year,monthname (datetimecol)作为 Month 按提取物分组(YEAR _ MONTH FROM datetimecol)按年(datetimecol)定单,按月(datetimecol)定单;

结果:

年、月

2021年1月 2021年2月 2021年3月 2021年4月 2021年5月 2020年5月 2020年6月 2020年7月 2020年8月 2020年9月 2020年10月 2020年11月 2020年12月

(这是我需要的结果)

我的观察 1. 当我按年(datetimecol)、月(datetimecol)分组使用时,没有给出期望的结果... 可能是因为 datetime 字段..。 2. 当我用 GROUP BY EXTRACT (YEAR _ MONTH FROM datetimecol)按年份(datetimecol)进行第二次查询时,它的工作非常好。

总之,对于逐年获取月份,使用以下查询。

从表中选择 Year (datetimecol)作为 Year,monthname (datetimecol)作为 Month 按提取物分组(YEAR _ MONTH FROM datetimecol)按年(datetimecol)定单,按月(datetimecol)定单;

由于这些数据是按月提取用于交易总结的,因此我必须做同样的事情,并且只想添加我使用的代码。我拥有的数据以字符串形式保存在数据库中,这样您的查询可能会更简单。不管怎样,作为一名交易员,这本质上是大多数人会寻找的:

select
DATE(DATE_FORMAT(STR_TO_DATE(closeDate, '%Y-%m-%d'), '%Y-%m-01')) AS month_beginning,
COUNT(*) AS trades,
TRUNCATE(sum(profitLoss)/count(*),2) as 'avgProfit',
TRUNCATE(sum(percentGain)/count(*),2) as 'avgPercent',
sum(profitLoss) as 'gi',
sum(profitLoss > 0)/count(*) AS winPercent,
sum(profitLoss < 0)/count(*) as 'lossPercent',
max(profitLoss) as bigWinner,
min(profitLoss) as bigLoser
from tradeHistory
group by month_beginning
order by month_beginning DESC

但是,它将跳过数据中缺失的月份。所以如果没有 Jan 的数据,就不会有争吵。