【发布时间】:2016-02-18 18:11:41
【问题描述】:
我有一个表,用作员工、部门和公司设置的分层数据集。员工可以在任何部门工作,如果他们没有指定,他们会继承部门设置。更具体的设置胜出,我想编写一个查询来获取特定员工/部门对的设置。
设置表有一个employeeid 可以为null,departmentid 也可以为null。如果两者都为空,则为公司范围设置的行。 "nvl(employeeid,0) 和 nvl(departmentid,0)" 有唯一的约束。
设置示例数据集:
employeeid departmentid address phone
null null 123 Corp Dr. 800-555-1212
10 null 1 ABC Ave. null
null 1 2 Dept Rd. null
null 2 3 Dept Rd. 617-555-1212
当我对员工 10 和部门 1 运行查询时,我应该得到一行: 地址 = 1 ABC Ave,电话 = 800-555-1212
对于员工 10 和部门 2,我应该获得更新的电话号码: 地址 = 1 ABC Ave,电话 = 617-555-1212
到目前为止,我能做的最好的事情是使用 first_value,忽略空值,在表上并按我添加的优先级排序。问题是 first_value over 不是聚合的,所以我需要一个单独的外部查询来选择特定的优先级。在我看来,这就像我应该能够聚合的东西。
select
address,
phone
from (
select
precedence,
first_value(address ignore nulls) over (order by precedence) address,
first_value(phone ignore nulls) over (order by precedence) phone
from (
select
1 precedence,
*
from
settings
where
settings.employeeid = ?
and settings.departmentid is null
union
select
2 precedence,
*
from
settings
where
settings.departmentid = ?
and settings.employeeid is null
union
select
3 precedence,
*
from
settings
where
settings.departmentid is null
and settings.employeeid is null
)
)
where
precedence = 3
这得到了正确的答案,但我觉得好像应该有一种方法可以在中间查询中将 first_values 汇总为聚合并删除外部查询,并且可能仅依赖联合的显式排序而不是引入优先级列,尽管这不太重要。
我为此使用 Oracle 11。
【问题讨论】:
-
您可以在
ORDER BY的FIRST_VALUE()中使用CASE表达式。 -
查看您的、我的和 Alex 的工作 - 您是否还必须为员工包括多行的可能性(一个部门为空,以及该员工 ID 为非空部门 ID 的多行?) 如果是这样,那么我们所有的优先级计算都需要更多的工作。