无法显示平均销售额,包括没有销售额的地区

时间:2020-02-09 18:53:00

标签: sql null case aggregate-functions

无法显示包括没有销售的地区在内的输出。

保险公司保留其员工的销售记录。每个员工都被分配到一个州。各州按地区分组。下表包含数据:

TABLE regions
  id INTEGER PRIMARY KEY
  name VARCHAR(50) NOT NULL

TABLE states
  id INTEGER PRIMARY KEY
  name VARCHAR(50) NOT NULL
  regionId INTEGER NOT NULL REFERENCES regions(id)

TABLE employees
  id INTEGER PRIMARY KEY
  name VARCHAR(50) NOT NULL
  stateId INTEGER NOT NULL REFERENCES states(id)

TABLE sales
  id INTEGER PRIMARY KEY
  amount INTEGER NOT NULL
  employeeId INTEGER NOT NULL REFERENCES employees(id)  

管理层需要比较区域的销售分析报告。

编写一个查询,返回:

The region name.
Average sales per employee for the region (Average sales = Total sales made for the region / Number of employees in the region).
The difference between the average sales of the region with the highest average sales, and the average sales per employee for the region (average sales to be calculated as explained above).

也应退回没有销售的地区。计算第二列和第三列时,使用0作为该地区每个员工的平均销售额。

这是到目前为止的代码:

SELECT regions.name, 
(CASE WHEN sales.amount<>0 THEN SUM(sales.amount)/COUNT(employees.id)ELSE 0 end)
AS average_sale,
(CASE WHEN sales.amount<>0 THEN SUM(sales.amount)/COUNT(employees.id)-MAX(sales.amount) ELSE 0 end) 
AS Diff
FROM regions
JOIN states
ON states.regionId = regions.Id
JOIN employees
ON states.id=employees.stateId
JOIN sales
ON employees.id=sales.employeeId
GROUP BY regions.Id;

6 个答案:

答案 0 :(得分:2)

如果您是从here到达此帖子的,那么我们需要进行查询以传递所有边缘情况。最重要的是:“员工可以进行多次销售。”

该地区每名员工的平均销售额(平均销售额=该地区的总销售额/该地区的员工人数)。

请记住,我们正在由每位员工完成多次销售。因此,我们需要准确计算该地区的员工人数。员工人数的不同将为我们提供正确的价值,而每位员工的平均销售额也将是准确的。

左联接,以便我们获得某些员工销售额的NULL值,这使我们获得了没有销售额的区域,该区域将显示为零。

让我们尝试一下:

with SalesAvg as (
  select R.name as rgn, 
    CASE WHEN SUM(IFNULL(SL.amount,0)) = 0 THEN 0                    /*region with no sales returning 0*/
    ELSE  SUM(IFNULL(SL.amount,0)) / COUNT(DISTINCT E.id) END as average             
/*distinct employee count gives the correct value for number of employees in ther region.*/
  from regions R
    left join states S on R.id = S.regionId
    left join employees E on S.id = E.stateId
    left join sales SL on E.id = SL.employeeId
  group by R.Id, R.name
) 
select 
  rgn, 
  average,
  (select max(average) from SalesAvg)- average as difference        /*highest average sales -region average*/
from SalesAvg
group by rgn

答案 1 :(得分:1)

with c as (
select sum(sales.amount)/count(employee.id) as average from regions region1
left join states state on region1.id = state.regionId
left join employees employee on state.id = employee.stateId
left join sales sales on sales.employeeId = employee.id 
group by region1.id)

select region.name, 
(case when sum(sales.amount)<>0 then sum(sales.amount)/count(employee.id) else 0 end) 
as average, 
(case when sum(sales.amount)<>0 then (select max(average) from c) -     
(sum(sales.amount)/count(employee.id))  
else (select max(average) from c) end) 
as difference
from regions region
left  join states state on region.id = state.regionId
left  join employees employee on state.id = employee.stateId
left  join sales sales on sales.employeeId = employee.id
group by region.id

答案 2 :(得分:1)

select regions.name, avg(coalesce(sales.amount,0)) as average
from regions
left join states
on regions.id=states.regionId
left join employees 
on states.id=employees.stateId
left join sales
on employees.id=sales.employeeid
group by (regions.name)
order by avg(sales.amount)  desc

答案 3 :(得分:0)

SELECT r.name, 
   COALESCE(SUM(COALESCE(s.amount, 0)), 0)/COALESCE(COUNT(e.Name), 0) AS avg_amount,
    ABS(COALESCE(SUM(COALESCE(s.amount, 0)), 0)/COALESCE(COUNT(e.Name), 0) -
(SELECT MAX(amount)
FROM
(SELECT COALESCE(SUM(s.amount), 0)/COALESCE(COUNT(e.Name), 0) AS amount
    FROM sales s
    JOIN employees e
    ON s.employeeid = e.Id
    JOIN states st
    ON st.id = e.stateid
    JOIN regions r
    ON r.id = st.regionid
    GROUP BY r.name))) AS diff
FROM  sales s
JOIN employees e
ON s.employeeid = e.Id
JOIN states st
ON st.id = e.stateid
JOIN regions r
ON r.id = st.regionid
GROUP BY r.name

答案 4 :(得分:0)

WITH c AS (
  SELECT regions.name AS name,
  (CASE WHEN sales.amount <> 0
    THEN SUM(sales.amount) / COUNT(employees.id) 
   ELSE 0 END) AS average
  FROM regions 
    LEFT JOIN states ON regions.id = states.regionid
    LEFT JOIN employees ON states.id = employees.stateId 
    LEFT JOIN sales ON employees.id = sales.employeeid
GROUP BY regions.id)

SELECT name, 
    average,
    (SELECT MAX(average) FROM c) - average as difference
FROM c
GROUP BY name

答案 5 :(得分:0)

with D as(
select regions.name as name, 
    case when sum(coalesce(sales.amount,0)) = 0 then 0
   else sum(coalesce(sales.amount,0))/count( distinct employees.id)

以平均结束 来自地区 左连接状态 在regions.id=states.regionId 左加入员工 在 states.id=employees.stateId 左加入销售 在Employees.id=sales.employeeid 分组依据(region.name) 按 avg(sales.amount)) 排序 选择名称, 平均, (从 D 中选择 max(average)-average 作为差异 来自 D;