Created date between that particular month mysql - mysql

I have a table event, where i have records with a field end_date, so my problem is i want to fetch number of records, grouping month wise, where end_date should with in that month only, so for example:
If a record have end_date as 2013-01-01 00:00:00 then it should be counted in January 2013, and i am not able to do that. I am unable to put that where condition, how to do tell database that end_date should be between the month for which it is currently grouping.
SELECT COUNT(*) AS 'count', MONTH(created) AS 'month', YEAR(created) AS 'year' FROM event WHERE is_approved =1 GROUP BY YEAR(created), MONTH(created)
Please help me out.
EDIT :
Data say i have is like:
Record name end_date
record_1 2013-11-01 00:00:00
record_2 2013-11-30 00:00:00
record_3 2013-12-01 00:00:00
record_4 2013-12-04 00:00:00
record_5 2013-12-06 00:00:00
record_6 2013-12-10 00:00:00
...many more
Result Expected is:
Count month year
2 11 2013
4 12 2013
....so on

Try this:
SELECT COUNT(1) AS 'count', MONTH(end_date) AS 'month', YEAR(end_date) AS 'year'
FROM event
WHERE is_approved = 1
GROUP BY EXTRACT(YEAR_MONTH FROM end_date);
OR
SELECT COUNT(1) AS 'count', MONTH(end_date) AS 'month', YEAR(end_date) AS 'year'
FROM event
WHERE is_approved = 1
GROUP BY YEAR(end_date), MONTH(end_date);
::EDIT::
1. end date is greater than that particular month - Simply add where condition in your query and pass particular month in format of YYYYMM instead of 201411
2. event is started - Add one more where condition to check whether the created date is less then current date
SELECT COUNT(1) AS 'count', MONTH(end_date) AS 'month', YEAR(end_date) AS 'year'
FROM event
WHERE is_approved = 1 AND
EXTRACT(YEAR_MONTH FROM end_date) > 201411 AND
DATE(created) <= CURRENT_DATE()
GROUP BY EXTRACT(YEAR_MONTH FROM end_date);
OR
SELECT COUNT(1) AS 'count', MONTH(end_date) AS 'month', YEAR(end_date) AS 'year'
FROM event
WHERE is_approved = 1 AND
EXTRACT(YEAR_MONTH FROM end_date) > 201411 AND
DATE(created) <= CURRENT_DATE()
GROUP BY YEAR(end_date), MONTH(end_date);

The count is aggregated based on the month and year so if you are spanning years, you wont have Jan 2013 mixed with Jan 2014, hence pulling those values too and that is the same basis of the group by.
As for your criteria, that all goes in the WHERE clause. In this case, I did anything starting with Jan 1, 2013 and ending Dec 31, 2014 via 'yyyy-mm-dd' standard date recognized format. That said, and the structure of the table you provided, I am using the "end_date" column.
SELECT
YEAR(end_date) AS EventYear,
MONTH(end_Date) AS EventMonth,
COUNT(*) AS EventCount
FROM
event
WHERE is_approved = 1
and end_date between '2013-01-01' and '2014-12-31'
GROUP BY
YEAR(end_date),
MONTH(end_Date)
Now, if you want them to have the most recent events on the top, I would put the year and month descending so 2014 is listed first, then 2013, etc and months within them as December (month 12), before the others.
GROUP BY
YEAR(end_date) DESC,
MONTH(end_Date) DESC
Your criteria could be almost anything from as simple as just a date change, approved status, or even get counts per account status is so needed, such as (and these are just EXAMPLES if you had such code status values)
SUM( is_approved = 0 ) as PendingEvent,
SUM( is_approved = 1 ) as ApprovedEvent,
SUM( is_approved = 2 ) as CancelledEvent
Per comment feedback.
For different date ranges, ignore the between clause and change the WHERE to something like
WHERE end_date > '2014-08-01' or all after a date...
where end_date < '2014-01-01' or all before a date...
They will still group by month / year. If you wanted based on a start date of the event, just change that column in instead, or do IN ADDITION to the others.

MySQL has a bunch of date and time functions that can help you with that. For example:
MONTH() Return the month from the date passed
or
YEAR() Return the year
So you can just get the month and year of your dates. And group your results by them.
SELECT
COUNT(*) cnt
,MONTH(end_date) month
,YEAR(end_date) year
FROM events
GROUP BY month, year
Result :
cnt month year
2 11 2013
4 12 2013
Update:
For filtering only the records that have an end_date greater than a particular month AND have already started, you just need to add a WHERE clause. For example, if the particular month were February 2015:
SELECT
COUNT(*) cnt
,MONTH(end_date) month
,YEAR(end_date) year
FROM events
WHERE end_date >= '2015-03-01'
AND created < NOW()
GROUP BY month, year
Alternatively, the first part of the WHERE clause can be rewritten in the following way, which is probably more comfortable to use if you have to pass the year and month as distinct parameters.
...
WHERE (YEAR(end_date) > 2015
OR (YEAR(end_date) = 2015 AND MONTH(end_date) > 02))
AND created...

SELECT COUNT(*) AS 'count', MONTH(created) AS 'month', YEAR(created) AS 'year' FROM event WHERE is_approved =1 and month(created) = "the month u want" and year(created) = "the year you want" group by GROUP BY YEAR(created), MONTH(created)
you will need to pull the month and year... i could help with that but not sure how you are getting it but months would be 01/02/03 ect and year is 2013/2014/2015 ect

Related

Retrieving all posts count with date sorts date wrong

I'm trying to make a chart where the X axis is the date (last 14 days) and the chart itself shows the count of the post on that date. However, it starts with 1. oct -> 9. oct and then proceeds with 25. sep -> 30.sep
My SQL:
SELECT DATE_FORMAT(created_at, "%d. %b") AS date, count(*) as count
FROM posts
WHERE created_at BETWEEN NOW() - INTERVAL 14 DAY AND NOW()
Group by date
ORDER BY date ASC
Image of the issue: https://i.imgur.com/d8AIRu6.png
The problem is that date in the order by clause references the alias defined in the select clause, that is a string representation of the date. You can't use that to sort the resultset as you want.
Here is one workaround: add another expression to the group by clause that has a date datatype - you can then use it to order the results:
SELECT date_format(created_at, '%d. %b') AS date, count(*) as count
FROM posts
WHERE created_at BETWEEN NOW() - INTERVAL 14 DAY AND NOW()
Group by date, date(created_at)
ORDER BY date(created_at) ASC

Get record of Jan of current Year in MYSQL

How can we get record of first or second month of current year in MySQL query?
Like I want this data for January and then for February:
select Sum(amount) as Amount from tbl_incomes where created_at = 'here the month January OR February of current year should be claused'
You can use the following, using YEAR and MONTH:
SELECT SUM(amount) AS Amount
FROM tbl_incomes
WHERE YEAR(created_at) = YEAR(NOW()) AND MONTH(created_at) IN (1, 2)
In case you want the SUM for January and February in separate rows you can use this:
SELECT SUM(amount) AS Amount
FROM tbl_incomes
WHERE YEAR(created_at) = YEAR(NOW()) AND MONTH(created_at) IN (1, 2)
GROUP BY YEAR(created_at), MONTH(created_at)
You should use a range expression.
SELECT sum(amount) amount
FROM tbl_incomes
WHERE created_at >= concat(year(now), '-01-01')
AND created_at < concat(year(now), '-03-01');
That way an index on created_at can support the query.

MySQL group by DAY not showing results of current month

As the query states, it retrieves records from june to august, but why is the results only display until july 31st?, i have records from 2014-06-08 to 2014-08-07. Does it have a problem since the current month as of today is august?
SELECT COUNT(*) AS, DATE(created)
FROM battle
WHERE player_id = 1234 AND enemy_id = 4567
AND created BETWEEN '2014-06-01 00:00:00' AND '2014-08-31 23:59:59'
GROUP BY DAY(created)
ORDER BY created ASC;
You're grouping by DAY(created), which is just the day of the month. So it's combining June 1, July 1, and August 1 into the same group, June 2, July 2, and August 2 into the next group, and so on.
Use GROUP BY DATE(created) to include the month in the grouping.
Change your query as follows
Use GROUP BY DATE(created) instead of GROUP BY DAY(created)
SELECT COUNT(*) AS, DATE(created)
FROM battle
WHERE player_id = 1234 AND enemy_id = 4567
AND created BETWEEN '2014-06-01 00:00:00' AND '2014-08-31 23:59:59'
GROUP BY DATE(created)
ORDER BY created ASC;
Try this:
SELECT COUNT(*) AS, DATE
FROM battle
WHERE player_id = 1234 AND enemy_id = 4567
AND Date BETWEEN '2014-06-01 00:00:00' AND '2014-08-31 23:59:59'
GROUP BY Date
ORDER BY Date ASC;

Sql Query - group by month from 1st day up todays date

I have a record set of sales amount daily with different branches.
For example
Date Amount Branch
01/01/2014 30 A
01/01/2014 30 B
01/02/2014 40 A
01/02/2014 40 B
01/03/2014 30 A
01/03/2014 30 B
up to feb,mar,apr,may,jun,jul,aug
What i want to achieve is to group the record monthly based on todays date day.
For example today is 08/11/2014. the range should be 1st day of the month "1" then i will pick the day today which is 11. So the range for all the months is 1-11. See below sample.
Date Range for query monthly
01/01/2014-01/11/2014
02/01/2014-02/11/2014
03/01/2014-03/11/2014
04/01/2014-04/11/2014
05/01/2014-05/11/2014
06/01/2014-06/11/2014
07/01/2014-07/11/2014
08/01/2014-08/11/2014
Group this date range and get the sum of total sales.
Please help
This should do most of the work:
SELECT MONTH(date), SUM(amount)
FROM table_name
WHERE DAY(date) <= DAY(CURDATE())
AND date >= YEAR(CURDATE())
GROUP BY MONTH(date);
UPDATE
For the 3 letter month tag, also you'll probably want an ORDER BY to be sure:
SELECT DATE_FORMAT(date,'%b'), SUM(amount)
FROM table_name
WHERE DAY(date) <= DAY(CURDATE())
AND date >= YEAR(CURDATE())
GROUP BY MONTH(date)
ORDER BY MONTH(date);
You should be able to achieve what you want by using the following MySQL query:
select sum('amount') from 'some_table'
where dayofmonth('sell_date') >= 1
and dayofmonth('sell_date') < dayofmonth(currdate())
group by month('sell_date');
I hope it works, did not have some database to test.
You could eventually also group by branch, by adding an additional , 'branch' before the query's semicolon.

MySQL group by week

I have a large number of records with a transaction datetime field going back several years. I would like to do a comparative analysis between the same timespan this year and last. How can I group by week over a 3 month range?
I'm running into problems using the YEARWEEK and WEEK functions because of the day the year 2012 starts of versus the day 2011 starts on.
Given that I have records with datetimes everyday from Jan 1st to the current day, and records with the same datetimes from the prior year, how can I group by week so the output is sums with dates like: 01/01/2011, 01/08/2011, 01/15/2011, etc., and 01/01/2012, 01/08/2012, 01/15/2012, etc.?
My query so far is as follows:
SELECT
DATE_FORMAT(A.transaction_date, '%Y-%m-%d') as date,
ROUND(sum(A.quantity), 3) AS quantity,
ROUND(sum(A.total_amount), 3) AS amount,
A.product_code,
D.fuel_type_code,
D.fuel_type_name,
C.customer_code,
C.customer_name
FROM
cl_transactions AS A
INNER JOIN
card AS B ON A.card_number=B.card_number
INNER JOIN
customer AS C ON B.customer_code=C.customer_code
INNER JOIN
fuel_type AS D ON A.fuel_type=D.fuel_type_code
WHERE
((A.transaction_date >= DATE_FORMAT(NOW() - INTERVAL 3 MONTH, '%Y-%m-01')) OR (A.transaction_date - INTERVAL 1 YEAR >= DATE_FORMAT(NOW() - INTERVAL 15 MONTH, '%Y-%m-01') AND A.transaction_date <= NOW() - INTERVAL 1 YEAR))
GROUP BY
A.transaction_date, fuel_type_code;
I would essentially like something that achieves the following pseudo-query:
GROUP BY
STARTING FROM THE OLDEST DATE (A.transaction_date + INTERVAL 6 DAY)
I started with an inner query using sqlvariables to build out from/to ranges for this year and last year of each respective start of year/month/day (ex: 2012-01-01 and 2011-01-01 respectively). From that, I'm also pre-formatting the date for final output so you have ONE master date basis for display reflecting that of whatever the "this year" week would be.
From that, I do a join to the transaction table where the transaction date is BETWEEN the respective start of current week and start of next week. Since date/time stamps include hour minute, 2012-01-01 by itself is implied as 12:00:00am (midnight) of the day. and between will go UP TO 7 days later 12:00:00 am. And that date will become the start date of the following week.
So, by joining on the date being between EITHER last yr or this yr time period, its the same group qualification. So the field selection does a ROUND( SUM( IF() )) per respective last year or this year. if the incoming transaction date is LESS than the current year's week start, then it must be a record from prior year, otherwise its for the current year. So, respectively, add the value itself, or zero as it applies.
So now, you have the group by. The week that it qualified for was already prepared from the inner query via "ThisYearWeekOf" formatted column, regardless of the otherwise computed "YEARWEEK()" or "WEEK()". The date ranges took care of that qualification for us.
Finally, I added the fuel-type as a join and included that as the group by. You have to group by all non-aggregate columns for proper SQL, although MySQL lets you get by by just grabbing the first entry for the given group if it is NOT so specified in group by.
To close, I DID include the information for the customer as you didn't have it in the group by and did not appear to be applicable... it would just arbitrarily grab one. However, I've added it to the group by, so now your records will show at the per customer level, per product and fuel type, how much sales and quantity between this year and last.
SELECT
JustWeekRange.ThisYearWeekOf,
CTrans.product_code,
FT.fuel_type_code,
FT.fuel_type_name,
C.customer_code,
C.customer_name,
ROUND( SUM( IF( CTrans.transaction_date < JustWeekRange.ThisYrWeekStart, CTrans.Quantity, 0 )), 3) as LastYrQty,
ROUND( SUM( IF( CTrans.transaction_date < JustWeekRange.ThisYrWeekStart, CTrans.total_amount, 0 )), 3) as LastYrAmt,
ROUND( SUM( IF( CTrans.transaction_date < JustWeekRange.ThisYrWeekStart, 0, CTrans.Quantity )), 3) as ThisYrQty,
ROUND( SUM( IF( CTrans.transaction_date < JustWeekRange.ThisYrWeekStart, 0, CTrans.total_amount )), 3) as ThisYrAmt,
FROM
( SELECT
DATE_FORMAT(#ThisYearDate, '%Y-%m-%d') as ThisYearWeekOf,
#LastYearDate as LastYrWeekStart,
#ThisYearDate as ThisYrWeekStart,
#LastYearDate := date_add( #LastYearDate, interval 7 day ) LastYrStartOfNextWeek,
#ThisYearDate := date_add( #ThisYearDate, interval 7 day ) ThisYrStartOfNextWeek
FROM
(select #ThisYearDate := '2012-01-01',
#LastYearDate := '2011-01-01' ) sqlvars,
cl_transactions justForLimit
HAVING
ThisYrWeekStart < '2012-04-01'
LIMIT 15 ) JustWeekRange
JOIN cl_transactions AS CTrans
ON CTrans.transaction_date BETWEEN
JustWeekRange.LastYrWeekStart AND JustWeekRange.LastYrStartOfNextWeek
OR CTrans.transaction_date BETWEEN
JustWeekRange.ThisYrWeekStart AND JustWeekRange.ThisYrStartOfNextWeek
JOIN fuel_type FT
ON CTrans.fuel_type = FT.fuel_type_code
JOIN card
ON CTrans.card_number = card.card_number
JOIN customer AS C
ON card.customer_code = C.customer_code
GROUP BY
JustWeekRange.ThisYearWeekOf,
CTrans.product_code,
FT.fuel_type_code,
FT.fuel_type_name,
C.customer_code,
C.customer_name