I need to query for the users with highest amount of sales by all projects, where the users are in users table, sales in units table, projects in projects table.
Projects Top Agent Total Sales for Project
Project A User A 100000
Project B User B 20000
Project C User A 1000
Project D - 0
The Projects column is list all the projects regardless it has sales or not.
The Top Agent column is list the user with the highest sales in the project.
The Total Sales for Project is the total sales for a projects.
The agent column i got is incorrect because there is someone else has the highest sales, the query seems to return the first row of the result
SELECT projects, pid, CASE WHEN agent is null THEN '-' ELSE agent END as agent,
CASE WHEN FORMAT(topagent,0) > 0 THEN FORMAT(topagent,0) ELSE 0 END as salesvolume
FROM (
SELECT projects.name as projects, projects.id as pid,
concat(users.f_name, ' ', users.l_name) as agent,
SUM(units.price) AS topagent
FROM users inner join bookings on bookings.agent_id = users.id
inner join units on bookings.unit = units.id
inner join types on types.id = units.types_id
inner join projects on projects.id = types.project_id
WHERE units.status = 'Sold'
GROUP BY pid
union
select projects.name as projects, projects.id as pid,
concat(users.f_name, ' ', users.l_name) as agent,
SUM(units.price) AS topagent
from projects left outer join types on projects.id = types.project_id
left outer join units on types.id = units.types_id and units.status = 'Sold'
left outer join bookings on units.id = bookings.unit and units.status = 'Sold'
left outer join users on bookings.agent_id = users.id and units.status = 'Sold'
group by pid
) a
GROUP BY pid
order by topagent desc
Your column aliases are confusing to read. In English, it seems what you mean by topagent
is "sum of sales by a human". But in SQL, your GROUP BY pid
means that the SUM(units.price)
really means "sum of sales in a project".
Then the UNION
adds a list of projects
to a list of users
. The agent names are basically random at this point.
If I decipher the requirements as "a list of projects ranked by the sales values of each project's top sales agent", then you'd have SQL as below:
SELECT
pid,
projects.name as project_name,
IFNULL(a.top_agent_name,'-') as top_agent_name,
CASE WHEN FORMAT(top_agent_sales,0) > 0 THEN FORMAT(top_agent_sales,0) ELSE 0 END as top_agent_salesvolume
FROM
projects
JOIN
SELECT
a.pid,
a.agent_name as top_agent_name,
a.agent_sales as top_agent_sales
FROM
(SELECT
projects.id as pid,
concat(users.f_name, ' ', users.l_name) as agent_name,
SUM(units.price) AS agent_sales
FROM users
inner join bookings on bookings.agent_id = users.id
inner join units on bookings.unit = units.id
inner join types on types.id = units.types_id
inner join projects on projects.id = types.project_id
WHERE units.status = 'Sold'
GROUP BY pid, users.id
) a # get all agents for all projects
JOIN
(SELECT
MAX(agent_sales) as max_project_agent_sales
FROM
(SELECT
projects.id as pid,
SUM(units.price) AS agent_sales
FROM users
inner join bookings on bookings.agent_id = users.id
inner join units on bookings.unit = units.id
inner join types on types.id = units.types_id
inner join projects on projects.id = types.project_id
WHERE units.status = 'Sold'
GROUP BY pid, users.id
)
GROUP BY pid) b ON a.pid = b.pid
WHERE
a.agent_sales = b.max_project_agent_sales
ORDER BY a.agent_sales desc
Old answer below:
There are 2 topagent
s for each pid
in the inner query since it's a union of 2 group by
s. There isn't a reducing function in the outer group by pid
so the topagent
returned in the select is the first one that came up in the inner query.
Try it if helps you-
SELECT a.prjname, IFNULL(usr.name,'-') AS Top_Agent, SUM(a.sale) AS Total_Sales_for_Project
FROM
(
SELECT prj.id AS prjid,prj.name AS prjname,usr.id,usr.name AS usrname,IFNULL(SUM(unit.price),0) AS sale
FROM projects AS prj
LEFT JOIN `types` AS typ ON typ.project_id=prj.id
LEFT JOIN units AS unt ON unt.type_id=typ.id AND unt.status='sold'
LEFT JOIN bookings bkg ON bkg.unit=unt.id
LEFT JOIN users usr ON usr.id=bkg.agent_it
GROUP BY prj.id,usr.id
ORDER BY prj.id,usr.id,sale DESC
) a
GROUP BY a.prjid
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.