问题思路是将数据中的日期和员工ID进行 full join,然后再和自己生成的dailysales临时表(员工ID,日期,销售额)进行left join,同时用coalesce将缺失值设成0(有员工当天无销售额),最后得出每个员工的每日销售额排名,自查思路找不出问题,但是运行结果不对。
with employee_daily_sale
as (
SELECT
EmployeeID, O.OrderDate,
SUM((1 - Discount) * OD.UnitPrice * Quantity) AS Sales_rev
FROM
Orders O
left join OrderDetails OD on O.OrderID = OD.OrderID
GROUP BY
EmployeeID, O.OrderDate
)
select D.OrderDate as date, E.EmployeeID, coalesce(Sales_rev,0) as rev, rank() over (partition by D.OrderDate order by Sales_rev desc) as e_Rank
from employees E cross join orders O
left join employee_daily_sale D on E.EmployeeID = D.EmployeeID and O.OrderDate = D.OrderDate;
运行结果如图:日期列出现了大量空值
没有原本数据怎么测试结果?提供些测试数据
可能存在以下几个问题:
1、with employee_daily_sale as 后面应该接 () 而不是 as,所以你需要把 as 改为 ()。
2、在 partition by D.OrderDate 中,应该使用别名 O.OrderDate,即 partition by O.OrderDate。
3、即使日期和员工ID的组合唯一,也需要使用 dense_rank 替换 rank 函数,因为可能有多名员工当天销售额相同,他们应该排名并列。
4、coalesce 函数的作用是将空值替换为指定的默认值,但在使用 left join 时,如果某员工当天没有销售额,那么 employee_daily_sale 表中会缺少这一条记录,因此 Sales_rev 字段会变成 null,而不是空值。你可以在 SELECT 子句中使用 ISNULL(Sales_rev, 0) 来处理这种情况。
修改后的代码如下:
with employee_daily_sale as (
SELECT
EmployeeID, OrderDate,
SUM((1 - Discount) * OD.UnitPrice * Quantity) AS Sales_rev
FROM
Orders O
LEFT JOIN OrderDetails OD ON O.OrderID = OD.OrderID
GROUP BY
EmployeeID, OrderDate
)
SELECT
O.OrderDate AS date,
E.EmployeeID,
ISNULL(Sales_rev, 0) AS rev,
DENSE_RANK() OVER (
PARTITION BY O.OrderDate
ORDER BY ISNULL(Sales_rev, 0) DESC
) AS e_Rank
FROM
Employees E
CROSS JOIN Orders O
LEFT JOIN employee_daily_sale D ON E.EmployeeID = D.EmployeeID AND O.OrderDate = D.OrderDate;