无法显示平均销售额(包括没有销售额的区域)

问题描述 投票:0回答:11

无法显示输出,包括没有销售的区域。

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

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).

没有销售的区域也应该退回。计算第 2 列和第 3 列时,使用 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;
sql null case aggregate-functions
11个回答
6
投票

如果您从这里到达这篇文章,我们需要一个能够通过所有边缘情况的查询。最重要的是:“员工可以有多个销售。”

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

请记住,我们每个员工都会完成多项销售。所以我们需要准确统计该地区的员工人数。明确的员工数量将为我们提供正确的值,并且每位员工的平均销售额也将是准确的。

左连接,以便我们获得某些员工销售额的 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
投票
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

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


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


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

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

以平均水平结束 来自地区 左连接状态 在regions.id=states.regionId上 左加入员工 关于 states.id=employees.stateId 左连接销售 在employees.id=sales.employeeid上 分组依据(地区.名称) 按平均值排序(销售额.金额)) 选择名称, 平均的, (从D中选择最大值(平均值))-平均值作为差值 来自 D;


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)

0
投票

我试图解决这个问题,并被困了很长时间。联系了一位专家并得到了使用不同员工计数的建议。这改变了游戏规则。

with sales_per_region as 
(
    select regions.name , COALESCE(sum(amount)/count(employees.id),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 1
),
max_sales_per_region as 
(
  select max(average) as max_average_sales
  from sales_per_region
)
select name, average, max_average_sales-average as difference
from sales_per_region,max_sales_per_region

0
投票

在mysql中试试这个方法

select region_name as name,avg_sales as average ,(max_sales-avg_sales ) as difference from 
(
with 
cte as (
select r.name as region_name,
coalesce((sum(ss.amount)/count(distinct e.id)),0) as avg_sales
from regions r 
left join states s on r.id=s.regionId
left join employees e on s.id=e.stateId
left join sales ss on e.id=ss.employeeId
group by r.name
      ) 
  
select region_name,avg_sales,
case 
  when avg_sales>=0 then (select max(avg_sales) from cte) end as max_sales 
 from cte 
)x;

0
投票

这在 MS SQL 中对我有用:

with sales_avg AS (
    select r.name as region, 
    case when sum(ifnull(s.amount,0)) = 0 then 0
    else sum(ifnull(s.amount,0))/count(distinct e.id) end as average
    from regions r
    left join states st on r.id = st.regionid
    left join employees e on st.id = e.stateid
    left join sales s on e.id = s.employeeid
    group by r.id, r.name)
 
select region, average, (select max(average) from sales_avg) - average as difference
from sales_avg
WITH sales_avg AS (
    SELECT 
        r.name AS region, 
        CASE
            WHEN SUM(ISNULL(s.amount,0)) = 0 THEN
                0
            ELSE 
                SUM(ISNULL(s.amount,0))/COUNT(distinct e.id)
        END AS average    
    FROM regions r
    LEFT JOIN states st 
        ON r.id = st.regionid
    LEFT JOIN employees e 
        ON st.id = e.stateid
    LEFT JOIN sales s 
        ON e.id = s.employeeid
    GROUP BY r.id, r.name)

0
投票

只通过了 3/4 测试 :c 所有地区都有销售,员工有零到多个销售:错误答案

    SELECT 
        region, 
        average, 
        (
            (SELECT MAX(average) FROM sales_avg) - average
        ) AS difference
    FROM sales_avg
    GROUP BY region, average
© www.soinside.com 2019 - 2024. All rights reserved.