I'm trying to get the last missing piece in my website unfortunately I need to generate sales report as well. I don't know where to start.
How can i display the records from a specific week, month, year. and total the amount
TABLE: payments.tbl
payment_id amount customer_id product_id trx_id currency payment_date
21 10470 1 15 5F110606611093636 PHP 2015-03-30
NOTE: payment_date structure is DATE
You get specific records with WHERE.
You get a total amount with SUM().
How to deal with dates depends on your DBMS, because different DBMS feature different date functions. Here is an example for MySQL:
select
sum(amount) as total_amount,
currency,
count(distinct customer_id) as number_of_different_customers,
count(distinct product_id) as number_of_different_products
from mytable
where month(payment_date) = month(curdate()) and year(payment_date) = year(curdate())
group by currency;
I group by currency here to get one result record per currency, as it makes no sense to sum amounts of different currencies.
Date functions for MySQL are found here: https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html.
Related
I am trying to get monthly sales totals from a MYSQL database and have them summed by month with month name for last X months. The two columns I am targeting are: total_customer_charged and local_time. I almost have my query working correctly, the problem I have is that the order the results come out sometimes changes with each query. Can anyone please give me some hints to get my query correct?
My existing query is:
select date_format(local_time,'%M'),sum(total_customer_charged) FROM ORDERS WHERE local_time BETWEEN curdate() - INTERVAL 3 MONTH AND curdate() group by month(local_time) order by year(local_time),month(local_time)
You should put year into the group-by statement like this:
select
date_format(local_time, '%Y') AS agg_year,
date_format(local_time, '%m') AS agg_month,
sum(total_customer_charged) AS monthly_total_customer_charged
FROM
ORDERS
WHERE
local_time BETWEEN curdate() - INTERVAL 3 MONTH AND curdate()
group by
date_format(local_time, '%Y'),
date_format(local_time, '%m')
order by
agg_year,
agg_month
SELECT MONTHNAME(local_time), SUM(total_customer_charged)
FROM ORDERS
GROUP BY YEAR(local_time), MONTH(local_time)
I am making a student web app. Amongst other tables, I have a table in which students enroll and enrollments are between two dates.
This app uses MySQL 5.6 and PHP 7.2
It has the following fields:
IDStudent
StartDate
EndDate
IDCourse
Each course has a maximum capacity in which it cannot be surpassed.
I want to know, given a start date, end date and IDCourse, how many concurrent students are in a course. I get an approxiumate value just counting rows between two dates
SELECT COUNT(*) FROM enrollments
WHERE IDCourse = ?
AND (
(StartDate BETWEEN "<start date>" AND "<end date>")
OR
(EndDate BETWEEN "<start date>" AND "<end date>")
OR
(StartDate <= "<start date>" AND EndDate>= "<end date>")
)
But that doesn't take account non overlapping ranges. It counts every enrollment.
For example, I have this very simple case:
Want to find how many students are enrolled between 01/01/2021 and 05/01/2021 at a specified course
And I have those 3 enrollments on that course:
01/01/2021 - 02/01/2021
03/01/2021 - 04/01/2021
20/12/2020 - 01/02/2021
I should get 2 count and not 3, because 1 and 2 don't overlap while 3 overlaps both.
I tried to search online but I didn't found something similar, maybe I am not using the correct keywords!
I found Determine max number of overlapping DATETIME ranges but that is for MySQL 8
Many thanks for your help
Regards
I think you may need to create a calendar table between the first start date and the last end date, count by date and then select the max between the period you are interested:
select max(stcount)
from
(
select c.dt, count(*) stcount from calendar_table c
join enrollments e on c.dt between e.StartDate and e.EndDate
group by c.dt
) countbydate
where dt between '2021-01-01' and '2021-01-05'
db-fiddle:
https://www.db-fiddle.com/f/dXuKMoRQ2ivLt5qi5AVFcG/0
I have 2 tables:
The first contains data for the current day (per hour) - this table has raw data, that needs to be processed.
The second contains data for previous day (per day) - this table already has the values calculated for every day.
I want to combine this to rows in a MySQL query, so that I return the data for previous dates (per day) and for current day (again, per day).
Currently I am using 2 mysql queries:
//table 1, data for current day
$qry1="
select DATE_FORMAT(completedate,'%Y-%m-%d') as date, SUM(IF(complete = 1,affpayout,0)) as pay, COUNT(*) as leads
from leads
where affiliateid={$_SESSION["id"]} AND completedate>'$date'
GROUP BY DATE_FORMAT(completedate,'%Y-%m-%d')";
//table 2, data for previous days, already processsed, we just need to select it
$qry2="
select DATE(date) as date, affrevenue as pay, totalleads as leads
from leadsdays
GROUP BY DATE(date)";
How can I combine the 2 efficiently (speed performance is an issue)? What would be the best way to do this?
Try to UNION. Also, make sure your tables are indexed properly. Looks like you'll want completedate and affiliateid indexed at least. Not sure how much more efficient two queries is versus one union though...
$qry = "(select
DATE_FORMAT(completedate,'%Y-%m-%d') as `date`,
SUM(IF(complete = 1,affpayout,0)) as pay,
COUNT(*) as leads
from leads
where affiliateid={$_SESSION["id"]} AND completedate>'$date'
GROUP BY DATE_FORMAT(completedate,'%Y-%m-%d'))
UNION
(select
DATE(`date`) as `date`,
affrevenue as pay,
totalleads as leads
from leadsdays
GROUP BY DATE(`date`))
ORDER BY DATE(`date`)";
I have 50 rows/entrys in my table Orders. I have a column, that holds when the order is claimed at, named claimed_at.
The date in this field are in this format: 2011-10-03 07:07:33
This is in the format (yy/mm/dd time).
I also have a column called price, this price is how much they paid.
I would like to display totals per day.
So for 6 orders from the date 2011-10-03, it should take the 6 order's price value, and plus them together.
So I can display:
2011-10-03 -- Total: 29292 Euros
2011-10-02 -- Total: 222 Euros
2011-09-28 -- Total: 4437 Euros
How can i do this?
You need to use aggregate functionality of MySQL in conjuction with some DATE conversion.
SELECT DATE(claimed_at) AS day
, SUM(price) AS total
FROM Orders
GROUP BY day
Create a new field say day with DATE_FORMAT(claimed_at,'%Y-%m-%d') AS day , sum the price and group by day so you will get the result you want.
Something like
SELECT DATE_FORMAT(claimed_at,'%Y-%m-%d') AS day,SUM(price) as total FROM orders GROUP BY day ORDER BY day DESC
Use grouping like this :
SELECT claimed_at, SUM(price) AS total
FROM Orders
GROUP BY claimed_at
You need to use function to get only date part(not time) in grouping. I dont know which function is used in mysql, in MSSQL it's CONVERT() function.
SELECT TRUNC(claimed_at), SUM(PRICE)
FROM my_orders_table
GROUP BY TRUNC(claimed_at)
I'm searching for a solution to this:
A customer can place a order with a price x at a time y. A customer can have unlimited number of orders.
I want to get the z top-customers with their ordering-amount within a time-frame (e.g.a month).
I'm stuck at the summing and the ordering / filtering to the top z.
Can you help me out? Thanks!
Given an orders table with customer_id, amount and time columns, you should be able to do something like this:
SELECT customer_id, sum(amount) AS total
FROM orders
GROUP BY customer_id
WHERE time BETWEEN start AND end
ORDER BY total DESCENDING
LIMIT 3
This is psuedo code, but I'd use something like:
select sum(order_total), client_id
from orders
where order_date between X and Y
group by client_id
order by sum(order_total)
limit 0, 10