Retrieve data for specific months - mysql

MySQL Query is like this
SELECT MONTHNAME(access_date) as date,
DATE_FORMAT( access_date, '%m/%Y' ) as month_date ,
COUNT( log_id ) as total_count
FROM user_activity_log
WHERE dam_id = (
SELECT dam_id
FROM dam_content_details
WHERE content_type= '$content_type'
)
AND access_date >= last_day(NOW() - INTERVAL ($month) MONTH)
GROUP BY MONTH( access_date )
ORDER BY access_date ASC
i will pass the numbers like 1,2,3.... then its giving value for that month.
The problem i faced is it retrieving the data per 30 days,60 days like that. I want if i will write $month = '1; then it should return the current month data & previous month data starting from day 1.
My sample output - $month = 2
date month_date total_count
--------- ------------ -----------
December 12/2013 4
January 01/2014 1
I want for december it should calculate from 12/01/2013. 1st December 2013. Any idea how to solve it ?

You just have to remove = from >=.
Try this:
SELECT MONTHNAME(access_date) as date,
DATE_FORMAT( access_date, '%m/%Y' ) as month_date ,
COUNT( log_id ) as total_count
FROM user_activity_log
WHERE dam_id = (SELECT dam_id FROM dam_content_details WHERE content_type= '$content_type') AND
access_date > LAST_DAY(NOW() - INTERVAL (($month)+1) MONTH)
GROUP BY MONTH( access_date )
ORDER BY access_date ASC

Related

Query that shows the total profit in descending order for each month in 2010?

I am supposed to write a query that shows the total profit in descending order for each month in 2010.
So far, I have a query that shows the total profits in descending order for 2010 and I have a query that can extract each month, but I can't seem to connect the two.
select (SalesPrice - AcquisitionPrice) profit, datesold
from Transaction
where DateSold >= '10-jan-01' and DateSold <= '10-dec-31';
and:
select to_char(datesold, 'mon')
from transaction
group by to_char(datesold, 'mon')
Oracle Query:
SELECT TRUNC( datesold, 'MM' ) AS "Month",
SUM( SalesPrice - AcquisitionPrice ) AS profit
FROM Transaction
WHERE EXTRACT( YEAR FROM datesold ) = 2010
GROUP BY TRUNC( datesold, 'MM' )
ORDER BY TRUNC( datesold, 'MM' ) DESC
MySQL and Oracle Query:
SELECT EXTRACT( MONTH FROM datesold ) AS mnth,
SUM( SalesPrice - AcquisitionPrice ) AS profit
FROM Transaction
WHERE EXTRACT( YEAR FROM datesold ) = 2010
GROUP BY EXTRACT( MONTH FROM datesold )
ORDER BY EXTRACT( MONTH FROM datesold ) DESC

How to display tree results count by each month?

I am trying to count achieve 3 results in one query:
Count all results where ‘app_creationdate’ = ('month') from current row
Count all results where ‘app_start’ = ('month') from current row
Count all results where ‘app_creationsdate’ < ‘app_start’ and ‘app_start’ = ('month') from current row
My Table:
app_id | app_creationdate(timestamp) | app_start(datetime)
00001 | 2014-11-17 19:39:04 | 2014-11-18 09:30:00
SELECT
DATE_FORMAT( app_creationsdate, '%m' ) AS 'month',
COUNT( app_id ) AS 'new',
(SELECT COUNT( app_id )
FROM appointments WHERE MONTH(app_start) = MONTH(NOW())) AS 'act',
(SELECT COUNT( app_id )
FROM appointments WHERE MONTH(app_creationsdate) < MONTH(app_start)) AS 'prev'
FROM appointments
WHERE app_owner = 2 AND app_creationsdate > DATE_SUB(now(), INTERVAL 12 MONTH)
GROUP BY DATE_FORMAT( app_creationsdate, '%Y%m' )
This may be closer to what you want. I'm still a bit confused about the prev scenario, so I did my best. I use EXTRACT(YEAR_MONTH FROM ...) to get the year and month, without the day, of each date so that we can do monthly comparisons. That's probably what you were trying to do with the DATE_FORMAT business.
SELECT DATE_FORMAT( app_creationsdate, '%m' ) AS 'month',
COUNT( app_id ) AS 'new',
-- get all other appointments that start in this month
(SELECT COUNT( act.app_id )
FROM appointments AS act
WHERE EXTRACT(YEAR_MONTH FROM act.app_start) = EXTRACT(YEAR_MONTH FROM appointments.app_creationsdate)) AS 'act',
-- get all appointments that were created before they started (???) and that started before this month
(SELECT COUNT( prev.app_id )
FROM appointments AS prev
WHERE EXTRACT(YEAR_MONTH FROM prev.app_creationsdate) < EXTRACT(YEAR_MONTH FROM appointments.app_creationsdate)
AND EXTRACT(YEAR_MONTH FROM prev.app_start) = EXTRACT(YEAR_MONTH FROM appointments.app_creationsdate)) AS 'prev'
FROM appointments
WHERE app_owner = 2
AND app_creationsdate > DATE_SUB(now(), INTERVAL 12 MONTH)
GROUP BY EXTRACT(YEAR_MONTH FROM app_creationsdate)
I am not entirely sure what you are trying to accomplish but I do notice one thing:
DATE_FORMAT(a2.app_start, '%m' ) = DATE_FORMAT('month', '%m' )
This: DATE_FORMAT('month', '%m' )...evaluates to NULL so equating that with anything is never going to work (I don't think anyway, but I'm new to MySQL... :) ).

How to select 6 months of data in MySQL, grouped between the 22nd and 21st of the next month

I have a table that contains the amount of data used each day, it looks something like this:
date | bytes
------------------
2014-01-1 | 12345
2014-01-2 | 56789
2014-01-3 | 78901
...
2014-02-1 | 12345
2014-02-2 | 56789
2014-02-3 | 78901
...
What I need to do is get the last 6 monthly totals, however the month must start on the 22nd day of the month and finish on the 21st day of the following month. For the current month it should start on the 22nd and finish today.
The best I can come up with is the following, the problem is - it is very messy and doesn't seem to give the correct result.
SELECT monthname(`date`),sum(`bytes`)
FROM `trafficDaily`
WHERE `date` between STR_TO_DATE( CONCAT( "22,", MONTH( NOW( ) )-6 , ",", YEAR( NOW( ) ) ) , "%d,%m,%Y" )
and STR_TO_DATE( CONCAT( "21,", MONTH( NOW( ) ) , ",", YEAR( NOW( ) ) ) , "%d,%m,%Y" )
group by month(DATE_SUB(`date`, INTERVAL 21 DAY))
order by `date`
Thank you in advance for your help.
You can do so by using user-defined variables to track the the change of month i.e in your case month starts from 21st
SELECT
MONTHNAME(STR_TO_DATE(group_day, '%m')) month_name ,
SUM(`bytes`) `sum`
FROM (
SELECT *,
#changemonth:= CASE
WHEN DAY(`date`) > 21
THEN #month
WHEN MONTH(`date`) <> #month
THEN #month
ELSE #month - 1
END group_day,
#month:= MONTH(`date`)
FROM
t ,(SELECT #changemonth:=0,
#month:= (SELECT MONTH(`date`) FROM t
WHERE `date` > NOW() - INTERVAL 6 MONTH ORDER BY `date` LIMIT 1) aa
) tt
WHERE `date` > NOW() - INTERVAL 6 MONTH
ORDER BY `date`
) a
GROUP BY group_day
Demo for last 3 months
Edit from comments for the case when January lies in last 6 month period
SELECT
MONTHNAME(
STR_TO_DATE(
CASE WHEN group_day < 1
THEN 12 ELSE group_day
END, '%m'
)
) month_name ,
SUM(`bytes`) `sum`
FROM (
SELECT *,
#changemonth:= CASE
WHEN DAY(`date`) > 21
THEN #month
WHEN MONTH(`date`) <> #month
THEN #month
ELSE #month - 1
END group_day,
#month:= MONTH(`date`)
FROM
t ,(SELECT #changemonth:=0,
#month:= (SELECT MONTH(`date`) FROM t
WHERE `date` > NOW() - INTERVAL 6 MONTH ORDER BY `date` LIMIT 1) aa
) tt
WHERE `date` > NOW() - INTERVAL 6 MONTH
ORDER BY `date`
) a
GROUP BY group_day
Demo with January
You have at least two options:
1st option
Create a calendar table and assign the 'business month' to each days. You can prepare your table for a long time period, then you can join to that table by date and you can do the grouping. If you have to do this calculation regularry, this is a good solution. (You can upgrade and use the calendar table to do several tasks)
2nd option
You can calculate the 'business month' by the date using the following query. (Please note, that I did not tested this query, so there could be typos).
SELECT
CASE
WHEN DAY(date) >= 22 THEN CONCAT(YEAR(date), '-', MONTH(date))
ELSE CONCAT(YEAR(date - INTERVAL 1 MONTH), '-', MONTH(date - INTERVAL 1 MONTH))
END AS m,
SUM(bytes)
FROM
log -- Use your table name instead :)
GROUP BY
CASE
WHEN DAY(date) >= 22 THEN CONCAT(YEAR(date), '-', MONTH(date))
ELSE CONCAT(YEAR(date - INTERVAL 1 MONTH), '-', MONTH(date - INTERVAL 1 MONTH))
END
You can adjust the calculation to your needs.

Same month two different SUMS

I'm trying to get different Sums for same month on same Year, just to get sums by different types. Tried using this code:
SELECT a.invoice_type, year( a.date ) AS Year,
date_format( a.date, '%M' ) AS `month` ,
Sum( x.amount * x.price ) AS sum FROM records x
JOIN paper_invoice a ON x.invoice_id = a.invoice_id
WHERE year( a.date ) = '2012'
GROUP BY a.invoice_type, Year( a.date ) , Month( a.date ) LIMIT 0 , 30
but it gives results in different rows:
http://www.part.lt/img/1505f0f13172922150febede85ddbf0925.png
But I need it to look like:
Year | Month | SUM_GRYNAIS | SUM_PAVEDIMU
2012 | January | 7597.14997705445 | 58740.2800849304
and ETC.
Try this:
SELECT Year, Month,
MAX(CASE WHEN invoice_type = 'GRYNAIS' THEN sum END) As Sum_GRYNAIS
MAX(CASE WHEN invoice_type = 'PAVEDIMU' THEN sum END) As SUM_PAVEDIMU
FROM
(
SELECT a.invoice_type, year( a.date ) AS Year,
date_format( a.date, '%M' ) AS `month` , Sum( x.amount * x.price ) AS sum
FROM records x JOIN paper_invoice a ON x.invoice_id = a.invoice_id
WHERE year( a.date ) = '2012' GROUP BY a.invoice_type, Year( a.date ) ,
Month( a.date ) LIMIT 0 , 30
)
GROUP BY Year, Month
Because each month has a different value. Try Group By on just the field year.
You are basically looking for PIVOT. MySql doesn't have a PIVOT function but you can still accomplish this. Here is an example of a PIVOT in MySql:
http://www.artfulsoftware.com/infotree/queries.php#78

SQL View to show interval of 12 months and by year

Right now one of the other programmers wrote this view to show interval of 6months. How do i write this so that it shows interval of 12 months grouped by month but only for year 2011
I'd like to copy it for a separate view of 12 months grouped by month but only for year 2012
CREATE ALGORITHM=UNDEFINED DEFINER=`root`#`%`
SQL SECURITY DEFINER VIEW `vw_dash_bymonth`AS
select
month(from_unixtime(`tbl_services`.`datetime`)) AS` month1`,
date_format(from_unixtime(`tbl_services`.`datetime`),'%Y') AS` year1`,
date_format(from_unixtime(`tbl_services`.`datetime`),'%d') AS `day1`,
`tbl_services`.`datetime` AS `realdate`,sum(`tbl_services`.`gallons`) AS `gallons`,
count(0) AS `service`,
round(avg(`tbl_services`.`gallons`),1) AS `average`
from `tbl_services`
where (from_unixtime(`tbl_services`.`datetime`) > (now() - interval 6 month))
group by month(from_unixtime(`tbl_services`.`datetime`))
If you look at the where clause
where (from_unixtime(`tbl_services`.`datetime`) > (now() - interval 6 month))
I believe this is getting the dates from everything from 6 months ago until today. If you want 12 months in 2011 I think you could replace that line with something like:
where (from_unixtime(`tbl_services`.`datetime`) >= DATE('2011-01-01 00:00:00'))
AND (from_unixtime(`tbl_services`.`datetime`) < DATE('2012-01-01 00:00:00'))
Although I don't know MySQL (just SQLServer) so if this doesn't work, hopefully someone else can tell me where I went wrong.
It can be simplified to:
where (from_unixtime(`tbl_services`.`datetime`) >= '2011-01-01')
AND (from_unixtime(`tbl_services`.`datetime`) < '2012-01-01')
SELECT DISTINCT FROM_UNIXTIME('date','%m-%Y') AS month,
COUNT(`id`) AS count
FROM 'blog'
GROUP BY month
ORDER BY month DESC LIMIT 0,12
SELECT
MONTH( UNIX_TIMESTAMP( t.`datetime`) ) AS month1,
DATE_FORMAT( UNIX_TIMESTAMP( t.`datetime`), '%Y' ) AS year1,
DATE_FORMAT( UNIX_TIMESTAMP( t.`datetime`), '%d') AS day1,
t.`datetime` AS realdate,
SUM(t.gallons) AS gallons,
COUNT(*) AS `service`,
ROUND( AVG( t.gallons ), 1 ) AS `average`
FROM
tbl_services AS t
CROSS JOIN
( SELECT 2011 AS YearToCheck
) AS c
WHERE t.`datetime` >= UNIX_TIMESTAMP( MAKEDATE( YearToCheck, 1 ) )
AND t.`datetime` < UNIX_TIMESTAMP( MAKEDATE( YearToCheck+1, 1 ) )
GROUP BY MONTH( FROM_UNIXTIME( t.`datetime` ) )