【问题标题】:SQL Left JOINING 3 TablesSQL Left JOINING 3 个表
【发布时间】:2016-08-24 19:30:27
【问题描述】:

我有 1 张桌子:

Contacts (ID integer, Name text, ATT_ID integer)

我的表充满了这些值:

(1, 'Alice', 1)
(2, 'Bob', 1)
(3, 'Carol', 1)
(4, 'Dave', 4)
(5, 'Eve', 4)
(6, 'Frank', 6)

目标是将这些联系人 ID 与配对的 ATT_ID 连接起来。

这是我当前的 SQL 代码:

SELECT t1.ID as ID, t1.Name , tt.Name , tt2.Name 
FROM Contacts as t1

LEFT JOIN (
SELECT MIN(t2.ID), t2.Name, t2.ATT_ID FROM Contacts as t2
WHERE t2.ID <> t2.ATT_ID) 
AS tt ON t1.ID = tt.ATT_ID

LEFT JOIN (
SELECT MAX(t3.ID), t3.Name, t3.ATT_ID FROM Contacts as t3
WHERE t3.ID <> t3.ATT_ID) 
AS tt2 ON t1.ID = tt2.ATT_ID

WHERE t1.ID = t1.ATT_ID;

我的结果是:

 Alice | Bob | null
 Dave  | null | Eve
 Frank | null | null

但是想要的结果应该是这样的:

Alice | Bob | Carol
Dave  | Eve | null
Frank | null | null

我怎样才能做到这一点?

【问题讨论】:

  • 哪个 RDBMS? MySQL、SQL Server Oracle 其他?
  • RDBMS:SQL 甲骨文

标签: sql oracle join max left-join


【解决方案1】:

假设您的 RDBMS 支持窗口函数...

这可以通过为每个子组生成一个行号并仅显示最小的行号来实现。

这也假设您在每组中不超过 3 个。

以下是特定于 ORACLE 的,但应该适用于 MS SQL 和 Postgresql 和 DB2。它不适用于 MySQL,因为不支持窗口函数。

注意 with 块只在 ORACLE 中有效。

With contacts (ID, Name, ATT_ID) as (    
Select 1, 'Alice', 1 from dual union all
Select 2, 'Bob', 1 from dual union all
Select 3, 'Carol', 1 from dual union all
Select 4, 'Dave', 4 from dual union all
Select 5, 'Eve', 4 from dual union all
Select 6, 'Frank', 6 from dual)

--FROM HERE ON should work if window functions supported.

Select * from (
Select T1.Name N1, T2.Name N2, T3.Name N3, Row_Number() Over (partition by T1.ATT_ID order by T1.ID) rn
FROM Contacts T1
LEFT JOIN Contacts T2
 on T1.ATT_ID = T2.ATT_ID
and T1.ID < T2.ID
LEFT JOIN contacts T3
 on T2.ATT_ID = T3.ATT_ID
and T2.ID < T3.ID
and T1.ID < T3.ID) B
WHERE RN =1 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-14
    • 2019-09-12
    • 1970-01-01
    • 2013-04-19
    • 2021-10-21
    • 2021-05-13
    • 1970-01-01
    相关资源
    最近更新 更多