MySQL show 12 month interval without first partial month - php

I want to list the scores, by month, for something that happened over the last 12 months. I noticed my query below was combining the results of the first partial month with the results of the last partial month. That is, my July report combined July 9-31, 2015 with July 1-8 2016 (now is July 8). I only want the latest month to represent the latest year. Here is what I was using...
$query = "SELECT record_id,
time_scored,
MONTH(time_scored) as month_added,
score, comment
FROM records
WHERE score IS NOT NULL AND
time_scored >= DATE_SUB(curdate(),INTERVAL 12 MONTH)
ORDER BY time_scored DESC";
Any help would be appreciated. Thanks!

Subtract 12 months from next months 1st day
$query = "SELECT record_id,
time_scored,
MONTH(time_scored) as month_added,
score, comment
FROM records
WHERE score IS NOT NULL AND
time_scored >= DATE_SUB(DATE_ADD(subdate(curdate(), (day(curdate())-1)), INTERVAL 1 MONTH),INTERVAL 12 MONTH)
ORDER BY time_scored DESC";

Related

Get last 12 months of data grouped by month even if 0

I am trying to get a COUNT of the last 12 months of appointments grouped by month for output into a chart. The following works fine but I need it to return 0 if no results for each month.
$query = "SELECT COUNT(id) as total_month FROM appointments WHERE created >= DATE(NOW()) - INTERVAL 365 DAY GROUP BY Month(created)";
$query = $mysqli->real_escape_string($query);
if($result = $mysqli->query($query)){
while($row = $result->fetch_array())
{
$month_total_appointments .= $row['total_month'].',';
}
}
echo $month_total_appointments;
================================================================
Simple table structure and example for appointments Table
id customer_name created
1 John 2020-05-01 08:00:00 <= stored as datetime
2 Mike 2020-04-01 09:00:00
3 Steve 2020-02-01 10:00:00
Output would be 0,0,0,0,0,0,0,0,1,0,1,1
======================================================
Current output is: 1,1,1
I've read some use a month table and LEFT JOIN but everything i've tried doesn't seem to work. Can anyone help please?
You won't get zeroes for rows that aren't there. Grouping combines rows that match particular criteria, but it can't fabricate them out of nothing.
That's why it's typical to include the grouping criteria in the results:
SELECT COUNT(id), MONTH(created) AS created_month
FROM appointments
WHERE created >= DATE(NOW()) - INTERVAL 365 DAY
GROUP BY created_month
Then you can expand that in your application code to fill in the missing values. The alternative is you need a fully populated list of all possible dates to JOIN against.
Keep in mind the MONTH() thing will wrap around and group January 2020 with January 2021. You may want to split this up:
SELECT COUNT(id), YEAR(created) AS created_year, MONTH(created) AS created_month
FROM appointments
WHERE created >= DATE(NOW()) - INTERVAL 365 DAY
GROUP BY created_year, created_month

PHP count rows for date range for previous month only and not from last 30 days to current date

I would like the database to count how many reports were generated for last month only and not from the current date backwards a month as it currently is e.g. 16/08/15 to 16/08/15. For example, I would like it to only count the total for August 2015, then once it is October, count the data for September 2015, so you can look back at the previous month how many reports were generated in the database.
I hope that makes sense? It will be used to count how many reports an employee has created to work out commission.
<?php
if ($result = $mysqli->query("SELECT count(inventory_id) cc FROM inventories WHERE inventory_date > CURRENT_DATE() - INTERVAL 1 MONTH")) {
$row = $result->fetch_assoc();
printf("<div class='col-6 statsMonth inventoryMonthStats'>Inventories in 30 days <span class='statCircle'>%d</span></div>", $row['cc']);
$result->close();
}
?>
Gets a bit ugly, but... assuming you always want "previous" month:
SELECT ...
...
WHERE YEAR(inventory_date) = YEAR(now() - interval 1 month)
AND MONTH(inventory_date) = MONTH(now() - interval 1 month)
If you want arbitrary previous months, then swap now() for a date in the month you want to calculate the "previous" of.

How can I get MySQL records from past 7 days, but only days that have a record, and return each day as a record?

Say I've got a simple mysql table with columns id, title, date. Each day can have several rows, but not every day has a row. For example there might be 5 rows with June 15th as the date, but zero rows with June 14th as the date. How can I get all results from the past 7 days, excluding June 14th because it has no rows. So I'm not just subtracting 7 days from the current date. I want to get only the past 7 days which have any rows at all.
Then I want to return each day as a single result, like a group by date, but by the year/month/day part of the timestamp, so that what I get back is only 7 results, and each result is like an array of individual rows.
I hope that makes sense. Any ideas?
Edit:
I realized I can do it something like this:
WHERE Date BETWEEN DATE_SUB( NOW(), INTERVAL DATEDIFF( NOW(), (SELECT Date FROM test GROUP BY Date LIMIT 7,1 ) ) DAY ) and NOW()
But this gives an SQL syntax error. What I'm trying to do is a subquery and group by date to get one result for each day, and return one result starting at offset 7, then do a DATEDIFF on that to get the number of days that DATE_SUB should put in the INTERVAL x DAYS
You won't be able to get the same day results back as an array, but you can group it by date, with the titles comma separated:
SELECT GROUP_CONCAT(title) AS titles, date
FROM test
WHERE date > DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY date;
Then in PHP, do something like this:
foreach ($results as $row)
{
echo $row['date'];
foreach ($row['titles'] as $title)
{
echo $title;
}
}
Figured it out: It works!
WHERE Date BETWEEN DATE_SUB(NOW(), INTERVAL (DATEDIFF( NOW(), (SELECT Date FROM test GROUP BY Date ORDER BY Date DESC LIMIT 8,1 ) ) ) DAY) and NOW()
I was missing a parentheses, and I had to add ORDER BY and DESC to the subquery.

group by unique month per year, not just month [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
MySQL Query GROUP BY day / month / year
I have the following mysql:
SELECT MONTH( FROM_UNIXTIME( `timeStamp` ) ) as month , COUNT( `id` ) as count
FROM `discusComments`
GROUP BY MONTH( FROM_UNIXTIME( `timeStamp` ) )
ORDER BY MONTH( FROM_UNIXTIME( `timeStamp` ) ) ASC
LIMIT 15
It gets the amount of entries made per month in the past 15 months. I was wondering WHY it only displayed the past 12 months ... then I realised the count was an aggregate of all years and not unique per month year. So the value for december could be 2012 and 2011 together.
I donÄt want this. I want to get the past 15 months and the amount of entries made for UNIQUE month year, e.g. december 2012, november 2012 etc.
The most straight forward idea I have on this is normally to change the format of the date value to a unique and speaking string, like 2012-12 for December 2012 and 2011-10 for October 2011 etc.
A function you can use for that is DATE_FORMAT():
DATE_FORMAT(FROM_UNIXTIME(timeStamp), '%Y-%m')
These strings are then easily sortable, e.g. ASC:
2011-10
2011-11
2011-12
...
2012-10
2012-11
2012-12
Example SQL query:
SELECT
DATE_FORMAT(FROM_UNIXTIME(timeStamp), '%Y-%m') as month,
COUNT(id) as count
FROM discusComments
GROUP BY month
ORDER BY month ASC
LIMIT 15
Add year to your SELECT column list and add the alias to GROUP BY too.
SELECT YEAR(FROM_UNIXTIME(`timestamp`)) AS year,
MONTH(FROM_UNIXTIME(`timestamp`)) AS month,
COUNT(`id`) AS count
FROM `discuscomments`
GROUP BY year,
month
ORDER BY year,
month
LIMIT 15
Try this
months_between(to_date ('2009/05/15', 'yyyy/mm/dd'),
to_date ('2009/04/16', 'yyyy/mm/dd'))

mysql select query

I search and get 10 records as result.I have two drop down boxes.one will have month as value and other one will have year as the value.Say those 10 records have same year and 5 have month as jan and other five has month as feb.
When user clicks feb then five ids will be passed to my query but i need to pull the younger document.2 docs were inserted on 5th of feb and other tow 10 feb and remaining one 25feb.i need to pull this 25th feb document.
how to select this using select statement?
You can extract day and time from the database and have them shown to the user so he can select the correct document, otherwise you can solve with:
SELECT *
FROM TABLE
WHERE month = 'Feb'
AND year = 2011
AND day = (select max(day) from table where month = 'Feb' and year = 2011 )
But I'm supposing a lot of information here, these infos should help me help you out:
name of table
fields and field types
Do you have a way to keep correct track of timestamps and dates?
Presumably you have some date_inserted column in your database - if so, you can add
ORDER BY date_inserted DESC LIMIT 1
This will put them in reverse date order, and LIMIT 1 will cause it to only return 1 result
This should work:
SELECT *
FROM `table`
WHERE MONTH(`insert_date`) = 2
AND YEAR(`insert_date`) = 2011
ORDER BY `insert_date` DESC
LIMIT 1;
Note: the above assumes you have a field in your table for storing the date on which the document was created/inserted. Please replace insert_date and table in the above query with the respective column name and table name.
EDITED after this comment "date stores date,month stores month and year stores year"
SELECT *
FROM `table`
WHERE `month` = 2
AND `year` = 2011
ORDER BY `year` DESC, `month` DESC, `date` DESC
LIMIT 1;
I've assumed that in the month column you are storing numbers, 1 for Jan, 2 for Feb and so on. If however you are storing the 3-letter month name, then instead of "`month` = 2" please use this:
MONTH(STR_TO_DATE(`month`, '%b')) = 2
Hope this should work.

Categories