Summarising MONTH value - sql

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

Related

getting sum for each month for several months in a year in sql

I have the following table
image of database in use
i want to get the following kind of results
jan 12500
feb 16500
mar 4500
apr 6500
the query should return a total for each month for desired months.
i know how to do this..
$sql = "SELECT SUM(cost) as january FROM earnings WHERE month= 1 and year= '$2022" ;
to get the sum for a given month but I cant find anything on how to get multiple months at once.
am still new to this
SELECT
SUM(cost) as cost,
month
FROM earnings
WHERE year = :year
GROUP BY month
Sum all entries of cost, per month (GROUP BY) found in year (:year)
Each ROW will have a column cost and month.
If you want to "further" filter the months you can apply another AND clause
AND (month >= 1 OR month <= 6) for January to June
Useful Source:
https://www.mysqltutorial.org/mysql-group-by.aspx

BigQuery : is it possible to execute another query inside an UDF?

I have a table that records a row for each unique user per day with some aggregated stats for that user on that day, and I need to produce a report that tells me for each day, the no. of unique users in the last 30 days including that day.
eg.
for Aug 31st, it'll count the unique users from Aug 2nd to Aug 31st
for Aug 30th, it'll count the unique users from Aug 1st to Aug 30th
and so on...
I've looked at some related questions but they aren't quite what I need - if a user logs in on multiple days in the last 30 days he should be counted only once, so I can't just sum the DAU count for the last 30 days.
Bigquery SQL for sliding window aggregate
BigQuery SQL for 28-day sliding window aggregate (without writing 28 lines of SQL)
So far, my ideas are to either:
write a simple script that'll execute a separate BigQuery for each of the relevant days
write a BigQuery UDF that'll execute basically the same query for each day selected from another query
but I've not found any examples on how to execute another BigQuery query inside an UDF, or if it's possible at all.
I need to produce a report that tells me for each day, the no. of
unique users in the last 30 days including that day.
Below should do this
SELECT
calendar_day,
EXACT_COUNT_DISTINCT(userID) AS unique_users
FROM (
SELECT calendar_day, userID
FROM YourTable
CROSS JOIN (
SELECT DATE(DATE_ADD('2016-08-08', pos - 1, "DAY")) AS calendar_day
FROM (
SELECT ROW_NUMBER() OVER() AS pos, *
FROM (FLATTEN((
SELECT SPLIT(RPAD('', 1 + DATEDIFF('2016-09-08', '2016-08-08'), '.'),'') AS h
FROM (SELECT NULL)),h
)))
) AS calendar
WHERE DATEDIFF(calendar_day, dt) BETWEEN 0 AND 29
)
GROUP BY calendar_day
ORDER BY calendar_day DESC
It assumes YourTable has userID and dt fields (like below for example)
dt userID
2016-09-08 1
2016-09-08 2
...
And you can control:
- reporting dates range by changing respectively 2016-08-08 and 2016-09-08
- aggregation size by changing 29 in BETWEEN 0 AND 29

How to write a Report query based on number of days in a month?

I am trying to write a query to generate automated report. This report is to run for last month's transactions it should run on 1st of every month. I have job to run this report to run 1st of every month. But how can I make this query to choose no of days in a month? (some months will have 30 and some will have 31 and in feb no of days changes based on leap year).
Here one more requirement is I only have to pass one parameter in the query. below is example of query that I have now
select id,name,address,trans_dt from tab1 where trans_dt between to_date('&1','MM-DD-YYYY')-30 AND to_date('&1','MM-DD-YYYY');
The above query is generating last 30 days transactions, but it will be wrong if no days for month is 31 or 28. I am using oracle 11r2 as database. Please help in writing this.
mySQL
SELECT
id,
NAME,
address,
trans_dt
FROM
tab1
WHERE
MONTH(trans_dt) = 02 /* Param for month passed in */
AND
YEAR(trans_dt) = YEAR(CURDATE())
Oracle
SELECT
id,
NAME,
address,
trans_dt
FROM
tab1
WHERE
to_char( dt_column, 'mm' ) = 02 /* Param for month passed in */
AND
EXTRACT(YEAR FROM DATE trans_dt) = trunc(sysdate, 'YEAR')
Maybe this can work? I only really know mySQL
Found solution but forget to reply here. Here is my solution
select id,name,address,trans_dt from tab1 where trans_dt between trunc(trunc(sysdate,'MM')-1,'MM') and trunc(sysdate,'MM');
above will give you report from 1st day of month to last day of month from calender.
select id
,name
,address
,trans_dt from tab1
where trans_dt between to_date(p_dt,'yyyy-mmm-dd') and add_months(to_date(p_dt,'yyyy-mmm-dd'))

Counting the number of occurrences of a certain month in SQL

I have a complex problem to solve with SQL query. I need to generate a report that gives a numerical value which represents a number of actions that users performed in each month of the year. For instance, if User1 performed the specified action in January and July, the query needs to return numbers 1 in column called 'January' and 'July' and 0 in columns that represent other month's. The table that I'm pulling the data from has only one column that contains the date and time on which the certain action was taken (this is the only column relevant to this specific problem). I need to make a SQL query that will return this informations for each user in a certain period.
Please help, and if you need any more informations please tell me and I will provide it.
Thanks
The structure of the result should be like this:
User Jan Feb ..... Dec
UID 1 0 1
I need this for every user that appears in the selected period. My application is using SQL server 2005.
select datepart(month, dateColumn) as Month
, count(*) as NumberOfActions
from Actions
group by
datepart(month, dateColumn)
The above query is correct, Though this will only return a number for the month.
I would do the following.
SELECT dateparth(month, dateColumn) as Month, count(*) as NumberOfActions
FROM Actions
GROUP BY Month
And then (if using php) consider mktime() and date() functions. Like this:
/* The year doesn't matter. we are just trying to format this in to a date */
$date = mktime(0, 0, 0, $row->Month, 1, 2012);
/* This will display 'Jan, Feb, Mar ...' respectively */
$dateText = date('M', $date);
If using another language then just google alternatives. It'll be the same principle .. just a different syntax.
Hope this helps.
This will return the data in rows but I think the OP is actually asking for it in columns. You will need a PIVOT statement for this, something like this...
Assuming...
Create Table TestPivot (UserName Varchar(10), DateColumn DateTime);
Then...
Select *
From (Select UserName, DateName(Month, DateColumn) As Month_Name, Count(*) As Month_Count
From TestPivot
Group By UserName, DateName(Month, DateColumn)) As SourcePart
Pivot (Sum(Month_Count)
For Month_Name In (January, February, March, April, May, June,
July, August, September, October, November, December)) As PivotPart

Group by month and year in MySQL

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