如何从没有常用值的不同表创建oracle视图

时间:2015-05-03 16:01:36

标签: sql database oracle join

我有以下表格

COMPANY

 =========================
 |COMPANY_ID|COMPANY_NAME|
 =========================
 |      C1  |  Test1     | 
 |      C2  |  Test2     |
 =========================

DEPARTMENT

 ========================
 |DEPT_ID   | DEPT_NAME |  
 ========================
 |     D1   |  Sales    | 
 |     D2   |  HR       |
 ========================

COMPANY_DEPARTMENT_PROFILE  

 ====================================================
 |PROFILE_ID| DEPT_ID   | COMPANY_ID | PROFILE_VALUE|
 ====================================================
 |       1  |  D1       |    C1      |  ACTIVE      |
 |       2  |  D2       |    C1      |  INACTIVE    |
 ====================================================

DEFAULT_PROFILE  

 ========================================
 |DEFAULT_ID| DEPT_ID   |  PROFILE_VALUE|
 ========================================
 |       1  |  D1       |    ACTIVE     |
 |       2  |  D2       |    ACTIVE     |
 ========================================

表逻辑是这样的,我们维护一个可用公司和部门的表,这些表并不相互依赖。让我们说,COMPANY表中的所有公司都有DEPARTMENT表中的所有部门。

COMPANY_DEPARTMENT_PROFILE具有公司相关的部门资料信息。该表可能包含也可能没有每个公司的数据。在此示例表中,COMPANY_DEPARTMENT_PROFILE仅包含公司C1的条目,而不包含C2。

DEFAULT_PROFILE包含每个部门的默认配置文件值,与公司无关。对于特定公司,可以通过COMPANY_DEPARTMENT_PROFILE中的值覆盖此数据。

现在我需要以下列格式创建视图

=============================================
|COMPANY_ID|DEPT_ID|PROFILE_ID|PROFILE_VALUE|
=============================================
|    C1    |  D1   |    1     |   ACTIVE    |
|    C1    |  D2   |    2     |   INVACTIVE |
|    C2    |  D1   |    1     |   ACTIVE    |
|    C2    |  D2   |    2     |   ACTIVE    |
=============================================

逻辑是我需要为每个公司的每个部门创建一个包含配置文件值的视图。如果公司已在COMPANY_DEPARTMENT_PROFILE中具有配置文件值,我们需要从那里获取值。但是,如果公司在COMPANY_DEPARTMENT_PROFILE中没有任何条目,那么我们需要从DEFAULT_PROFILE填充该部门的默认值。

1 个答案:

答案 0 :(得分:2)

您可以使用cross join生成所有公司和部门。然后使用left join和一些逻辑来引入其他配置文件信息以选择默认值:

select c.company_id, d.dept_id,
       coalesce(cdp.profile_id, dp.profile_id) as profile_id,
       (case when cdp.profile_id is not null then cdp.profile_value else dp.profile_value end) as profile_value
from company c cross join
     department d left join
     company_department_profile cdp
     on cdp.company_id = c.company_id and cdp.dept_id = cdp.dept_id left join
     default_profile dp
     on d.dept_id = dp.dept_id;