I am trying to find out how many times Kiln stopped in last three months. I have the following query:
SELECT SUM(kiln_no_stops) from monthly_report
where date BETWEEN DATE_FORMAT(NOW() - INTERVAL 3 MONTH, '%m-%Y')
AND DATE_FORMAT(NOW() , '%m-%Y')
When I use this query I get this error
Unknown column 'date' in 'where clause'.
But I am able to get the data for last one month using the query below:
SELECT SUM(kiln_no_stops)
from monthly_report
where date_format(yesterday,'%m-%Y')=Date_format(NOW() - INTERVAL 1 MONTH,'%m-%Y')
How can I get the data "Total number of stops" for the last three months?
Check if this would help you:
SELECT SUM(kiln_no_stops)
from monthly_report
where yesterday >= now()-interval 3 month;
EDIT:
To get last 3 months data (March1 to May31, current date = June 18)
SELECT SUM(kiln_no_stops)
from monthly_report where month(yesterday) < month(now())
AND yesterday >= cast( (last_day(now()) + interval 1 day - interval 4 month) as date);
Related
I have a table like this:
I need to sum how many messages were delivered per msisdn in last 8 weeks(but for each week) from date entered. Here is what I came up with:
SELECT count(*) as ukupan_broj, SUM(IF (sent_messages.delivered = 1,1,0 )) as broj_dostavljenih,
count(*) - SUM(IF (sent_messages.delivered = 1,1,0 )) as non_billed,
SUM(IF (sent_messages.delivered = 1,1,0 )) / count(*) as ratio,
`sent_messages`.`msisdn`,
MONTH(`sent_messages`.`datetime`) AS MONTH, WEEK(`sent_messages`.`datetime`) AS WEEK,
DATE_FORMAT(`sent_messages`.`datetime`, '%Y-%m-%d') AS DATE
FROM `sent_messages`
INNER JOIN `received_messages` on `received_messages`.`uniqueid`=`sent_messages`.`originalID`
and `received_messages`.`msisdn`=`sent_messages`.`msisdn`
WHERE `sent_messages`.`datetime` >= '2016-12-12'
AND `sent_messages`.`originalID` = `received_messages`.`uniqueid`
AND `sent_messages`.`datetime` <= '2017-12-30'
AND `sent_messages`.`datetime` >= `received_messages`.`datetime`
AND `sent_messages`.`datetime` <= ( `received_messages`.`datetime` + INTERVAL 2 HOUR )
AND `sent_messages`.`type` = 'PAID'
GROUP BY WEEK
ORDER BY DATE ASC
And because I'm grouping it by WEEK, my result is showing sum of all delivered, undelivered etc. but not per msisdn. Here is how result looks like:
And when I add msisdn in GROUP BY clause I don't get the result the way I need it.
And I need it like this:
Please help me to write optimized query to fetch these results for each msisdn per last 8 weeks, because I'm stuck.
WEEK(...) has a problem near the first of the year. Instead, you could use TO_DAYS:
WHERE datetime > CURDATE() - INTERVAL 8 WEEK -- for the last 8 weeks
GROUP BY MOD(TO_DAYS(datetime), 7) -- group by week
That is quite simple, but there is a bug in it. It only works if today is the last day of a "week". And if date%7 lands on the desired day of week.
WHERE datetime > CURDATE() - INTERVAL 9 WEEK -- for the last 8 weeks
GROUP BY MOD(TO_DAYS(datetime) - 3, 7) -- group by week
Is the first cut at fixing the bugs -- 9-week interval will include the current partial week and the partial week 8 weeks ago. The "- 3" (or whatever number works) will align your "week" to start on Monday or Sunday or whatever.
SUM(IF (sent_messages.delivered = 1,1,0 )) can be shortened to SUM(delivered = 1) or even SUM(delivered) if that column only has 0 or 1 values.
I need to do a select where I can chose to see results for current month, previous month, 1 month ago, 2 months ago, 3 months ago.
I found this question: MySQL: Query to get all rows from previous month, but I'm stuck with a filter that will get me all the results for 2 months ago from first to last day of the month.
I tried with this but it doesn't work:
SELECT * FROM table
AND MONTH(date_created) = MONTH(1 MONTH - INTERVAL 2 MONTH);
Try this:
SELECT * FROM table
WHERE MONTH(date_created) = MONTH(NOW() - INTERVAL 2 MONTH)
AND (
YEAR(date_created) = YEAR(NOW())
OR
YEAR(date_created) = YEAR(NOW() - INTERVAL 2 MONTH)
);
Returning records CREATED PRIOR the last 2 months only in MySQL.
If you want all rows from 2 months ago, then use logic like this:
WHERE date_created >= DATE_SUB(DATE_SUB(CURDATE(), 1 - DAY(CURDATE())), INTERVAL 2 MONTH) AND
date_created < DATE_SUB(DATE_SUB(CURDATE(), 1 - DAY(CURDATE())), INTERVAL 1 MONTH)
What is this doing? First, it is only applying functions to the current date part of the expression. This allows MySQL to use an index on date_created, if available and appropriate.
The expression DATE_SUB(CURDATE(), 1 - DAY(CURDATE()) is simply a way to get the first day of the month.
You query have an error, correct one would be:
SELECT * FROM table
WHERE MONTH(date_created) = MONTH(DATE_SUB(NOW(),INTERVAL 2 MONTH))
For current month just MONTH(NOW()), replace "2" with any number of months you need (1,3,.. 23)
as mentioned in comments this solution ignores YEAR differences, it just selects all records with the same month, no matter the year
you can filter wrong year results with additional clause:
AND YEAR(date_created) = '2019' # or year you need
Or use more complex query:
SELECT * FROM table
where
date_created between
/* first day of -2 month*/
date_sub(date_sub(now(),interval 2 month), interval (day(now())-1) day)
and
/* last day of -2 month*/
last_day(date_sub(now(),interval 2 month))
I have searched and viewed a lot of answers on SO but even trying to apply all I found I get incorrect results.
I am trying to group my mysql results by week mon-sun, and by month from day 1 to last day of month
I have tried different types of grouping like:
GROUP BY YEARWEEK(data)
GROUP BY WEEK(data)
for weeks and
GROUP BY MONTH(data)
for months
all these grouping methods return uncorrect groupings. some results start in random days of the month or the week.
this is example query which get results from last month entries divided by week although the week grouping is not resulting in weeks from mon-sun.
SELECT *, count(id) AS count FROM leadz WHERE YEAR(data) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH) AND MONTH(data) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH) GROUP BY YEARWEEK(data)
these are the week segments I get as results:
2016-07-01 2016-07-04 2016-07-16 2016-07-17 2016-07-25 2016-07-31
Next is a sample query of total entries grouped by month, again gropuing does not start from 1st of the month
SELECT *, count(id) AS count FROM leadz GROUP BY MONTH(data)
these are the month segments I get as result:
2016-04-18 2016-05-25 2016-06-01 2016-07-25 2016-08-02
Any help appreciated
For starting on monday you should use
YEARWEEK(data, 1)
or
WEEK(data,1)
see this for ref http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_week
so your select should be
SELECT *, count(id) AS count
FROM leadz
WHERE YEAR(data) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(data) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
GROUP BY YEARWEEK(data, 1)
I have a table with a timestamp field. How do I get data from the last 3 months?
In particular, March is my current month let say, 03/2012. I need to return records from the months March, February, and January only.
3 months before today:
select * from table where timestamp >= now()-interval 3 month;
Start with first of month:
select * from table where timestamp >= last_day(now()) + interval 1 day - interval 3 month;
To get the first day of the current month, you could use this:
DATE_FORMAT(CURDATE(), '%Y-%m-01')
if current date is 2013-03-13, it will return 2013-03-01, and we can just substract 2 months from this date to obtain 2013-01-01. Your query could be like this:
SELECT *
FROM yourtable
WHERE data >= DATE_FORMAT(CURDATE(), '%Y-%m-01') - INTERVAL 2 MONTH
I know this is an old question, but to possibly save others time and to sum the above answers up for the case of needing (1) dates from current month and (2) dates from the prior 2 months (common when displaying data statistics):
WHERE ((timestamp >= NOW() - DATE_FORMAT(CURDATE(), '%Y-%m-01'))
OR (timestamp >= DATE_FORMAT(CURDATE(), '%Y-%m-01') - INTERVAL 2 MONTH))
Assuming you're using SQL Server (Oracle, MySQL and others have similar date functions), you can use the dateadd function to add or subtract an interval to the current date.
If you want a full three months, you can subtract 3 months from today : DATEADD(m,-3,getdate())
But, as you state, you only want data from January, February and March. You have to make some calculation based on today's date: dateadd(m,-2, CONVERT(datetime, CONVERT(VARCHAR(2), MONTH(getdate())) + '/01/' + CONVERT(VARCHAR(4), YEAR(getdate()))))
And in the end, get a query like
SELECT fields
FROM table
WHERE timestampfield > DATEADD(m,-2, CONVERT(datetime, CONVERT(VARCHAR(2), MONTH(getdate())) + '/01/' + CONVERT(VARCHAR(4), YEAR(getdate()))))
--- edit ---
erf, I just noticed the "mysql" tag... you can get more information on MySQL date functions here : https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
Another possibility would be:
SELECT * WHERE your_date_column > LAST_DAY(CURRENT_DATE - INTERVAL 3 MONTH);
Use this code here to get the previous 3 months from a certain date
SELECT * FROM table WHERE date_column>= DATE_FORMAT(current_date(), '%Y-%m-01') - INTERVAL 3 MONTH and date_column< DATE_FORMAT(current_date(), '%Y-%m-01')
WHERE ((timestamp >= NOW() - DATE_FORMAT(CURDATE(), '%Y-%m-01'))
OR (timestamp >= DATE_FORMAT(CURDATE(), '%Y-%m-01') - INTERVAL 2 MONTH))
I found the following code to help in creating a weekly report based on a start date of Friday. The instructions say to replace ".$startWeekDay." with a 4. When I put '".$startDay."' as '2013-01-30', I get errors.
Also I get a report by day rather than week as I desire.
SELECT SUM(cost) AS total,
CONCAT(IF(date - INTERVAL 6 day < '".$startDay."',
'".$startDay."',
IF(WEEKDAY(date - INTERVAL 6 DAY) = ".$startWeekDay.",
date - INTERVAL 6 DAY,
date - INTERVAL ((WEEKDAY(date) - ".$startWeekDay.")) DAY)),
' - ', date) AS week,
IF((WEEKDAY(date) - ".$startWeekDay.") >= 0,
TO_DAYS(date) - (WEEKDAY(date) - ".$startWeekDay."),
TO_DAYS(date) - (7 - (".$startWeekDay." - WEEKDAY(date)))) AS sortDay
FROM daily_expense
WHERE date BETWEEN '".$startDay."' AND '".$endDay."'
GROUP BY sortDay;
The following code is what I am using
SELECT count(DISTINCT (
UserID)
) AS total, CONCAT(IF(date(LastModified) - INTERVAL 6 day < date(LastModified),
date(LastModified),
IF(WEEKDAY(date(LastModified) - INTERVAL 6 DAY) = 4,
date(LastModified) - INTERVAL 6 DAY,
date(LastModified) - INTERVAL ((WEEKDAY(date(LastModified)) - 4)) DAY)),
' - ', date(LastModified)) AS week
FROM `Purchase`
WHERE `OfferingID` =87
AND `Status`
IN ( 1, 4 )
GROUP BY week
The output I get is
total week
3 2013-01-30 - 2013-01-30
1 2013-01-31 - 2013-01-31
I'm not sure exactly how you want to display your week, the sql above is attempting to display date ranges. If this isn't a requirement, your query could be very simple, you can just offset your time by two days (since friday is two days away from the natural star of the week) and use the week function to get the week number.
The query would look like this:
select count(distinct (UserID)) as total
, year( LastModified + interval 2 day ) as year
, week( LastModified + interval 2 day ) as week_number
FROM `Purchase`
WHERE `OfferingID` =87
AND `Status`
IN ( 1, 4 )
group by year, week_number;