Group by month and year in MySQL - sql

Given a table with a timestamp on each row, how would you format the query to fit into this specific json object format.
I am trying to organize a json object into years / months.
json to base the query off:
{
"2009":["August","July","September"],
"2010":["January", "February", "October"]
}
Here is the query I have so far -
SELECT
MONTHNAME(t.summaryDateTime) as month, YEAR(t.summaryDateTime) as year
FROM
trading_summary t
GROUP BY MONTH(t.summaryDateTime) DESC";
The query is breaking down because it is (predictably) lumping together the different years.

GROUP BY YEAR(t.summaryDateTime), MONTH(t.summaryDateTime);
is what you want.

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

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

I know this is an old question, but the following should work if you don't need the month name at the DB level:
SELECT EXTRACT(YEAR_MONTH FROM summaryDateTime) summary_year_month
FROM trading_summary
GROUP BY summary_year_month;
See EXTRACT function docs
You will probably find this to be better performing.. and if you are building a JSON object in the application layer, you can do the formatting/ordering as you run through the results.
N.B. I wasn't aware you could add DESC to a GROUP BY clause in MySQL, perhaps you are missing an ORDER BY clause:
SELECT EXTRACT(YEAR_MONTH FROM summaryDateTime) summary_year_month
FROM trading_summary
GROUP BY summary_year_month
ORDER BY summary_year_month DESC;

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
Should use DESC for both YEAR and Month to get correct order.

You must do something like this
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

This is how I do it:
GROUP BY EXTRACT(YEAR_MONTH FROM t.summaryDateTime);

use EXTRACT function like this
mysql> SELECT EXTRACT(YEAR FROM '2009-07-02');
-> 2009

You cal also do this
SELECT SUM(amnt) `value`,DATE_FORMAT(dtrg,'%m-%y') AS label FROM rentpay GROUP BY YEAR(dtrg) DESC, MONTH(dtrg) DESC LIMIT 12
to order by year and month. Lets say you want to order from this year and this month all the way back to 12 month

You are grouping by month only, you have to add YEAR() to the group by

SELECT YEAR(t.summaryDateTime) as yr, GROUP_CONCAT(MONTHNAME(t.summaryDateTime)) AS month
FROM trading_summary t GROUP BY yr
Still you would need to process it in external script to get exactly the structure you're looking for.
For example use PHP's explode to create an array from list of month names and then use json_encode()

As this data is being pulled for a trade summary by month, I had to do the same thing and would just like to add the code I use. The data I have is saved in the database as a string so your query may be simpler. Either way, as a trader, this is in essence what most people would be looking for:
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
However, it will skip months that are missing in your data. So if there is no data for Jan, there won't be a row.

I would like add difference between group by year(datetime),month(datetime) and groupb by extract(year_month from datetime).
here is the query i tried with these two cases.
select year(datetimecol) as Year,monthname(datetimecol) as Month from table
group by year(datetimecol) and month(datetimecol) order by year(datetimecol) desc;
result:
Year, Month
2020, May
select year( datetimecol) as Year,monthname(datetimecol) as Month from table
GROUP BY EXTRACT(YEAR_MONTH FROM datetimecol) order by year(datetimecol) desc,month(datetimecol) asc;
result:
Year, Month
2021, January
2021, February
2021, March
2021, April
2021, May
2020, May
2020, June
2020, July
2020, August
2020, September
2020, October
2020, November
2020, December
(this is the result i need)
My observation
1.when i am using with group by year(datetimecol),month(datetimecol) , not giving desired result ..might be because of datetime feild...
2.when i tired second query with GROUP BY EXTRACT(YEAR_MONTH FROM datetimecol) order by year(datetimecol)...its working absolutely fine.
in conclusion, for getting months by year wise use the following query.
select year( datetimecol) as Year,monthname(datetimecol) as Month from table
GROUP BY EXTRACT(YEAR_MONTH FROM datetimecol) order by year(datetimecol) desc,month(datetimecol) asc;

Use
GROUP BY year, month DESC";
Instead of
GROUP BY MONTH(t.summaryDateTime) DESC";

Related

how to use group by with current year months and another data field in sequelize

related table
I need GROUP BY createdAt's month and status in the current year using sequelize.
my expected output is:-
expected output
(might need to adjust syntax according to your db):
SELECT DATE_TRUNC('month', createdAt) as month,
status,
COUNT(id)
FROM table
GROUP BY 1, 2
If you really only want the month number use DATE_PART instead of DATE_TRUNC

Convert date into individual numerical columns for year month and day SQL

I have a date column in the format YY-MON-DD, e.g. 25-JUN-05. Is it possible to isolate this into 3 separate columns for year, month and day? Where month is converted from text to numerical, e.g. Year: 25, Month: 06, Day: 05?
MS SQL SERVER
As Nebi suggested, you can use DATEPART and extract each part and store it into different columns.
SELECT DATEPART(DAY,'2008-10-22'); -- Returns DAY part i.e 22
SELECT DATEPART(MONTH,'2008-10-22'); -- Returns MONTH part i.e 10
SELECT DATEPART(YEAR,'2008-10-22'); -- Returns YEAR part i.e 2008
Try with the below script,if you are using SQL Server.
SELECT 'Year: '+CAST(LEFT(YourdateColumn,2) as VARCHAR(2))+', Month: ' +CAST(MONTH('01-'+SUBSTRING(YourdateColumn,4,3)+'-15')as VARCHAR(2))+', Day:'+CAST(RIGHT(YourdateColumn,2)as VARCHAR(2))
FROM Yourtable
sample output :
You didn't specify your DBMS.
The following is standard SQL assuming that column really is a DATE column
select extract(year from the_column) as the_year,
extract(month from the_column) as the_month,
extract(day from the_column) as the_day
from the_table;

Summarising MONTH value

I have a simple statement that starts:
SELECT a.product, MONTH(a.saledate) AS Month, Count(*) AS Total
Which yields, for example,
Product Month Total
Bike 8 1000
Please can anyone advise if it's possible to add the month's name to this query and also, is it possible to get a monthly total to appear as well?
Thanks!
The query in your example counts all the rows in your table, then presents that count next to a randomly chosen row's product and sale date. That's -- almost certainly -- not what you want. MySQL is quirky that way. Other DBMSs reject your example query.
If you want to display a monthly summary of product sold, here's the basic query:
SELECT a.product,
LAST_DAY(a.saledate) AS month_ending,
COUNT(*) AS Total
FROM table a
GROUP BY a.product, LAST_DAY(a.saledate)
The LAST_DAY() function is a great way to extract month and year from a date.
Finally, if you want to display the text name of the month, you can use the DATE_FORMAT() function to do that. %b as a format specifier gives a three-letter month name, and %M gives the full month name. So this query will do it.
SELECT a.product,
LAST_DAY(a.saledate) AS month_ending,
DATE_FORMAT(LAST_DAY(a.saledate), '%M %Y')) AS month
COUNT(*) AS Total
FROM table a
GROUP BY a.product, LAST_DAY(a.saledate)
In SQL Server 2012+ you can use the EOMONTH() function in place of LAST_DAY().
In SQL Server 2008+ you can use DATENAME(mm, a.saledate) to retrieve the month name from a date.
There are two ways of getting month name
1)
SUBSTRING('JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC ', (MONTH(a.saledate) * 4) - 3, 3)
2)
DATENAME(month, a.saledate)
Some poeple say You might be using MYSQL:
Then getting month name will be:
SELECT MONTHNAME( a.saledate);

How to get last and first date of every week from predefined date table (oracle SQL)

I have Table D_date in which all dates of a year, week number,quarter number etc attributes are defined. I just want to get first and last date of every week of year 2015.
Sample D_date tabe attached.
It is simple min/max if I understand you right
SELECT calendar_year_nbr, week, min(actual_date),max(actual_date)
FROM D_date
GROUP BY calendar_year_nbr, week
I just want to get first and last date of every week of year 2015.
Since you have precomputed values already stored in the table, you could directly use MIN and MAX as aggregate functions along with GROUP BY.
For example,
SELECT MIN(actual_date) min_date,
MAX(actual_date) max_date,
calendar_week_nbr
FROM d_date
WHERE calendar_year_nbr = 2015
GROUP BY calendar_week_nbr
ORDER BY min_date;
Another way is to use ROWNUM() OVER() analytic function.

SQL query for selecting specific date range (such as the current month only)

I am working in SQL Server 2012.
I am trying to collect all data for the current month (2015-07) and group them. When I run this query it selects only the current day.
SELECT
YEAR, MONTH, IDWHSE, IDLOCATION, IDCUST,
SUM(PALLETDAYS) AS PALLETDAYS,
COUNT(*) AS LOCATIONDAYS
FROM
[METRICS].[dbo].[DailyData]
WHERE
DATE = CONVERT(date, DATEADD(MM, 0, GETDATE()))
GROUP BY
YEAR, MONTH, IDWHSE, IDLOCATION, IDCUST, PALLETDAYS
Thanks in advance
Gerry
Try this:
SELECT
YEAR, MONTH, IDWHSE, IDLOCATION, IDCUST,
SUM(PALLETDAYS) AS PALLETDAYS,
COUNT(*) AS LOCATIONDAYS
FROM
[METRICS].[dbo].[DailyData]
WHERE
MONTH(DATE) = MONTH(SYSDATETIME())
GROUP BY
YEAR, MONTH, IDWHSE, IDLOCATION, IDCUST, PALLETDAYS
By using the MONTH() function, you get the month number - both of your column Date (which is a really horribly bad name for a column, since DATE is also a reserved keyword for a datatype in SQL Server 2012 - try to use something more meaningful than just Date!) and the current date (I prefer the SYSDATETIME() function over GETDATE())