多个连接未按预期加入

时间:2013-10-30 13:04:49

标签: sql oracle join left-join

我有以下表格

table 2 with a fk to table 1
table 3 with a fk to table 1

在表2中,我有两行链接到表1 在表3中,我有一行链接表1

我正在尝试制作一个有

的表格
| table1 pk  | table 2 pk | null |
| table1 pk  | table 2 pk | null |
| table1 pk  | null | table 3 pk |

然而,当我尝试以下内容时,我得到了

select tab1.id, tab2.id, tab3.id
from table1 tab1 
left join tab2 on tab1.id = tab2.tab1_id
left join tab3 on tab1.id = tab3.tab1_id

给出了这个表

| table1 pk  | table 2 pk | table 3 pk |
| table1 pk  | table 2 pk | table 3 pk |

有人可以帮忙解决这个问题吗?

提前致谢

修改

我想我可能有点过分了。理想情况下输出

| table1 pk  | table 2 pk |
| table1 pk  | table 3 pk |
| table1 pk  | table 3 pk |

一旦我加入此联接,它将被添加到另一个大规模查询......

3 个答案:

答案 0 :(得分:1)

一个不寻常的解决方案是

select coalesce(t2.tab1_id, t3.tab1_id) pk,
   t2.pk, t3.pk
from table2 t2 
   full join table3 t3
       on t3.tab1_id = t2.tab1_id
where exists (select * from table1
              where pk in (t2.tab1_id, t3.tab1_id)

注意(编辑)正如Andriy M在注释中所指出的那样,where子句只消除table2和table3中的行,其中表1中不存在FK,如果FK约束已正确应用于table2和table3,则不能存在。 / p>

答案 1 :(得分:1)

我在这里看不到任何疯狂的事情

WITH TAB1
    AS (SELECT 1 AS ID FROM DUAL
        UNION ALL
        SELECT 2 AS ID FROM DUAL
        UNION ALL
        SELECT 3 AS ID FROM DUAL),
    TAB2
    AS (SELECT 1 AS TAB1_ID, 'A' AS ID FROM DUAL
        UNION ALL
        SELECT 2 AS TAB1_ID, 'B' AS ID
        FROM DUAL),
    TAB3
    AS (SELECT 3 AS TAB1_ID, 'C' AS ID
        FROM DUAL)
SELECT
      TAB1.ID,
      COALESCE ( TAB2.ID,
               TAB3.ID )
FROM
      TAB1
      LEFT JOIN TAB2
          ON TAB1.ID = TAB2.TAB1_ID
      LEFT JOIN TAB3
          ON TAB1.ID = TAB3.TAB1_ID;

1   A   
2   B   
3   C

答案 2 :(得分:1)

您可以使用联接到联合的结果:

SELECT
  t1.table1pk,
  t23.table2pk,
  t23.table3pk
FROM table1 t1
INNER JOIN
(
  SELECT table2pk, NULL AS table3pk, table1fk
  FROM table2

  UNION ALL

  SELECT NULL AS table2pk, table3pk, table1fk
  FROM table3
) t23
ON t1.table1pk = t23.table1fk
;

或者你可以使用两个联接结果的联合:

SELECT
  t1.table1pk,
  t2.table2pk,
  NULL AS table3pk
FROM table1 t1
INNER JOIN table2 t2
ON t1.table1pk = t2.table1fk

UNION ALL

SELECT
  t1.table1pk,
  NULL AS table2pk,
  t3.table3pk
FROM table1 t1
INNER JOIN table3 t3
ON t1.table1pk = t3.table1fk
;

可以调整这两种方法以生成所需输出的两列版本:

  • 加入工会:

    SELECT
      t1.table1pk,
      t23.otherpk
    FROM table1 t1
    INNER JOIN
    (
      SELECT table2pk AS otherpk, table1fk
      FROM table2
    
      UNION ALL
    
      SELECT table3pk AS otherpk, table1fk
      FROM table3
    ) t23
    ON t1.table1pk = t23.table1fk
    ;
    
  • 联合联盟:

    SELECT
      t1.table1pk,
      t2.table2pk AS otherpk
    FROM table1 t1
    INNER JOIN table2 t2
    ON t1.table1pk = t2.table1fk
    
    UNION ALL
    
    SELECT
      t1.table1pk,
      t3.table3pk AS otherpk
    FROM table1 t1
    INNER JOIN table3 t3
    ON t1.table1pk = t3.table1fk
    ;