Oracle FULL OUTER JOIN三个表有两个条件

guc*_*cce 0 sql oracle oracle12c

背景

Oracle DB版本:

SELECT * FROM v$version
WHERE banner LIKE 'Oracle%';
-- OUTPUT
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
Run Code Online (Sandbox Code Playgroud)

目标

我正在尝试使用两个条件外连接三个表,以便缺少值只显示为.请参阅以下详细信息.NULL

下表是抽象,因此请不要尝试改进数据模型本身.

测量

主键= ID

|  ID  |    MEAS_NAME    |
|------|-----------------|
| 1000 | "Measurement 1" |
Run Code Online (Sandbox Code Playgroud)

MEASUREMENT_AREA

主键=(ID,NAME)
外键ID=MEASUREMENT.ID

|  ID  |    NAME   | AREA |
|------|-----------|------|
| 1000 | "Point 1" |   10 |
| 1000 | "Point 2" |   20 |
Run Code Online (Sandbox Code Playgroud)

MEASUREMENT_VOLUME

主键=(ID,NAME)
外键ID=MEASUREMENT.ID

|  ID  |    NAME   | VOLUME |
|------|-----------|--------|
| 1000 | "Point 1" |    100 |
| 1000 | "Point 3" |    200 |
Run Code Online (Sandbox Code Playgroud)

预期结果

我想要的是以下输出:

|  ID  |    MEAS_NAME    |    NAME   | AREA | VOLUME |
|------|-----------------|-----------|------|--------|
| 1000 | "Measurement 1" | "Point 1" | 10   | 100    |
| 1000 | "Measurement 1" | "Point 2" | 20   | NULL   |
| 1000 | "Measurement 1" | "Point 3" | NULL | 200    |
Run Code Online (Sandbox Code Playgroud)

这意味着,如果一个特定的MEASUREMENT.ID和具体的NAME有两个数据AREA,并VOLUME随后把它们放在同一行.否则,只需将AREAVOLUME字段留空即可.

查询1

我想出了以下SQL语句,它不起作用,它丢弃了以下结果MEASUREMENT_VOLUME:

SELECT meas.ID AS "ID",
    meas.MEAS_NAME AS "MEAS_NAME",
    COALESCE (area.NAME, vol.NAME) as "NAME",
    area.AREA, vol.VOLUME
FROM MEASUREMENT meas
  LEFT JOIN MEASUREMENT_AREA area
    ON meas.ID = area.ID
  FULL JOIN MEASUREMENT_VOLUME vol
    ON meas.ID = vol.ID AND area.NAME = vol.NAME
WHERE meas.ID = 1000;
Run Code Online (Sandbox Code Playgroud)

查询2

如果我把MEASUREMENT它放在最后它工作,但查询非常慢:

SELECT meas.ID AS "ID",
    meas.MEAS_NAME AS "MEAS_NAME",
    COALESCE (area.NAME, vol.NAME) as "NAME",
    area.AREA, vol.VOLUME
FROM MEASUREMENT_AREA area
    FULL JOIN MEASUREMENT_VOLUME vol
        ON area.ID = vol.ID AND area.NAME = vol.NAME
    JOIN MEASUREMENT meas
        ON meas.ID = vol.ID OR meas.ID = area.ID
WHERE meas.ID = 1000;
Run Code Online (Sandbox Code Playgroud)

问题

  • 为什么查询1不起作用?
  • 为什么查询2有效?
  • 什么是实现输出的最有效方法?

非常感谢您的帮助,我不是SQL专家.

附加信息

  • 一行MEASUREMENT包含恰好一次测量的元数据
  • 一个测量可以包含数百个测量点,这些测量点由它们的名称区分.
  • MEASUREMENT_AREA并且MEASUREMENT_VOLUMEMEASUREMENT它们大得多,每个都包含超过1000万行

Tho*_*ner 6

为什么一个查询有效,另一个没有在另一个答案中解释.所以我只想添加我编写查询的方式:

你想的完全外部联接measurement_areameasurement_volume.在子查询中执行此操作并与measurement表连接:

select id, m.meas_name, data.name, data.area, data.volume
from measurement m
join 
(
  select id, name, ma.area, mv.volume
  from measurement_area ma
  full outer join measurement_volume mv using (id, name)
) data using(id);
Run Code Online (Sandbox Code Playgroud)