I have the following relevant columns in my 'orders' table:
Date_Day (is a range from 1 to 31 with no trailing 0)
Date_Month (is a range from January to December, not numerical)
Date_Year (is the year in 4 digit format, ex: 2005)
Total (number with 2 decimal places)
I know the way of storing date is absolutely awful, but this was the database I was given. I am trying to find a few things and I'm not sure if there is a way to do it in SQL instead of doing the math in PHP:
The SUM of each day of each year.
The SUM of this day last year
(where this day is the nth weekday of the month. So for today, it
would be the 1st Tuesday of October in 2012)
The highest grossing
day in history
MySQL is not my forte, and while I can figure it out in PHP, I would love to see it done in MySQL so I can start to learn it more.
If you want to keep your database structured as it is, you could use these queries:
The SUM of each day of each year:
SELECT Date_Year, Date_Month, Date_Day, SUM(Total)
FROM tablename
GROUP BY Date_Year, Date_Month, Date_Day
The SUM of this day last year:
SELECT SUM(Total)
FROM tablename
WHERE
Date_Year = YEAR(CURDATE())-1
AND Date_Month = MONTHNAME(CURDATE())
AND Date_Day = DAY(CURDATE())
The highest grossing day in history:
SELECT Date_Year, Date_Month, Date_Day, SUM(Total)
FROM tablename
GROUP BY Date_Year, Date_Month, Date_Day
ORDER BY SUM(Total) DESC
LIMIT 1
Related
I was given id, start_date, end_date in the dataset and was asking to find the average number of trips per day for each month in MySQL.
My query looks like:
SELECT
YEAR(start_date) AS Year,
MONTH(start_date) AS Month,
COUNT(*) / (COUNT(DISTINCT YEAR(start_date))) AS avg_trips_per_day
FROM
trips
GROUP BY Year , Month
ORDER BY Year , Month;
But the returning result for avg_trips_per_day was the total number of trips in that month instead. Any suggestions?
This shows you the average trips per travelled days for every Month and year
Spo when there where only five days this month with different startdate, it calculates the avg for every travelled day
SELECT
YEAR(start_date) AS 'Year',
MONTH(start_date) AS 'Month',
COUNT(*) / COUNT(DISTINCT start_date) avg_trips_per_day
FROM trips
GROUP BY YEAR(start_date),MONTH(start_date)
ORDER BY YEAR(start_date),MONTH(start_date);
See dbfiddle
If you want average number of trips per day for a month, you need to ultimately divide the number of trips made in a month by the number of days in that month. At least that is my understanding of what average number of trips per day for a month mean (i.e. the number of days in the month has to factor into the calculation). If I made 3 trips on 1/1/2020 and no other trips for the rest of the year, that would be an average of 3 trips per year. It would also be an average of 3 trips per month for the month of January, 2020. But it can only be 3/31 trips per day for the entire month.
If you only wanted to divide by the number of days on which trips were actually made, then the question should be worded, "How do you find the average number of trips per trip-days for each month ..." or words to that effect.
Also, I am not sure how you want to handle a trip that begins on one day and ends on another. This SQL just looks at the start date since that is what yours is doing:
select year(start_date) as start_year,
month(start_date) as start_month,
count(*) /
(select day(last_day(concat(start_year, '-', start_month, '-01')))) as avg
from trips
group by start_year, start_month
order by start_year, start_month
The expression select day(last_day(concat(start_year, '-', start_month, '-01'))) calculates the number of days in the month given by year start_year and month start_month, which is needed because the average number of trips per day for a month is the total number of trips for the month divided by the number of days in the month.
See Db Fiddle
You only need to change one word from YEAR to DAY or DATE.
SELECT
YEAR(start_date) AS Year,
MONTH(start_date) AS Month,
COUNT(*) / (COUNT(DISTINCT DAY(start_date))) AS avg_trips_per_day
FROM
trips
GROUP BY Year , Month
ORDER BY Year , Month;
OR
SELECT
YEAR(start_date) AS Year,
MONTH(start_date) AS Month,
COUNT(*) / (COUNT(DISTINCT DATE(start_date))) AS avg_trips_per_day
FROM
trips
GROUP BY Year , Month
ORDER BY Year , Month;
The reason why your result was the sum of all trips per month is because the
result of COUNT(DISTINCT YEAR(start_date)) is 1
So you could run both the queries below to view the difference.
SELECT
YEAR(start_date) AS Year,
MONTH(start_date) AS Month,
COUNT(*) AS total_trips_of_month,
COUNT(DISTINCT DAY(start_date)) AS days_having_trips_that_month,
COUNT(*) / (COUNT(DISTINCT YEAR(start_date))) AS avg_trips_per_day
FROM
trips
GROUP BY Year , Month
ORDER BY Year , Month
vs
SELECT
YEAR(start_date) AS Year,
MONTH(start_date) AS Month,
COUNT(*) AS total_trips_of_month,
COUNT(DISTINCT DAY(start_date)) AS days_having_trips_that_month,
COUNT(*) / (COUNT(DISTINCT DATE(start_date))) AS avg_trips_per_day
FROM
trips
GROUP BY Year , Month
ORDER BY Year , Month
I want to display month wise total, week wise total and then day wise total with days in one mysql query. I can do it using seperate queries but i want it in single query . Is it possible to display this hierarchy?
by using GROUP BY MONTH we found total by month and GROUP BY WEEK we found total by WEEK
Select sum(column) From table GROUP BY MONTH(column)
union
Select sum(column) From table GROUP BY WEEK(column)
and UNION operator combines the result
This is from link you have provided.
use UNION:
SELECT SUM(cost) AS total, MONTHNAME(date) AS month
FROM daily_expense
GROUP BY month
UNION
SELECT SUM(cost) AS total, CONCAT(date, ' - ', date + INTERVAL 6 DAY) AS week
FROM daily_expense
GROUP BY WEEK(date)
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
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.
I have a MySQL table called history that includes a column called month: January, February, March, etc. and a column called day_num containing day numbers from 1 to 31.
I need to be able to select a month and a day from the two corresponding columns, based on the current month and day.
I know it's a rather embarrasingly basic question, but - how do I do that?
SELECT month, day_num FROM history WHERE ??????? ORDER BY RAND() LIMIT 1;
Would appreciate a bit of advice from a knowledgeable person.
SELECT *
FROM History
WHERE DATE_FORMAT(CURDATE(), '%M') = `month` AND
DAY(CURDATE()) = `day_num`
SQLFiddle Demo
OR
SELECT *
FROM History
WHERE MONTHNAME(CURDATE()) = `month` AND
DAY(CURDATE()) = `day_num`
SQLFiddle Demo
Other Sources
MONTHNAME
DAY