【问题标题】:Join three tables on a common column在一个公共列上连接三个表
【发布时间】:2020-01-23 00:05:41
【问题描述】:

我有三个名为 Table1、Table2 和 Table3 的表。 Table1 有列(mobNum bigint,visitedUS DateTime)。 Table2 有列(mobNum bigint,visitedUK DateTime)。 Table3 有列(mobNum bigint,visitedChina DateTime)。样本数据如下

表1

___________________________       
    mobnum | visitedUS
___________________________ 
9000000001 |  20/10/18  
___________________________ 
9000000001 | 11/07/19  
___________________________ 
9000000002 | 01/02/17
___________________________

表2

    mobnum | visitedUK
___________________________ 
9000000001 | 03/05/19  
___________________________ 
9000000002 |10/10/18  
___________________________

表3

    mobnum | visitedChina
___________________________ 
9000000001 | 15/03/18 
___________________________ 

现在我希望 SQL 查询显示如下结果

              Result Table
   -------------------------------------------------------
   mobnum      | visitedUS    | visitedUK  | visitedChina  
   -------------------------------------------------------
     9000000001|20/10/18      |  03/05/19  |  15/03/18    
   -------------------------------------------------------
     9000000001|11/07/19      |  Null      |   Null       
   -------------------------------------------------------
     9000000002|01/02/17      | 10/10/18   |   Null       
   -------------------------------------------------------

【问题讨论】:

  • 其中一个答案是否为您解决了问题?

标签: sql sql-server


【解决方案1】:

试试这个:

with table1rn(mobnum, visitedUS, rn) as
(
select *, row_number() over(partition by mobnum order by visitedUS) rn
from table1
),
table2rn(mobnum, visitedUK, rn) as
(
select *, row_number() over(partition by mobnum order by visitedUK) rn
from table2
),
table3rn(mobnum, visitedChina, rn) as
(
select *, row_number() over(partition by mobnum order by visitedChina) rn
from table3
)
select t1.mobnum, t1.visitedUS, t2.visitedUK, t3.visitedChina
from table1rn t1
left join table2rn t2 on t2.mobnum = t1.mobnum and t2.rn = t1.rn
left join table3rn t3 on t3.mobnum = t1.mobnum and t3.rn = t1.rn

【讨论】:

    【解决方案2】:

    只需我的 2 美分,一个更干净的解决方案是使用 colesce 而不是多个 ISNULL:

    SELECT COALESCE(t1.mobnum, t2.mobnum, t3.mobnum) mobnum,
           t1.visitedUS,
           t2.visitedUK,
           t3.visitedChina
    FROM Table1 t1
        FULL OUTER JOIN Table2 t2 ON t1.mobnum = t2.mobnum
        FULL OUTER JOIN Table3 t3 ON t3.mobnum = ISNULL(t1.mobnum, t2.mobnum);
    

    【讨论】:

    • 我对合并一无所知。它更干净。我建议在连接语句中使用它也只是为了保持一致性/相似性。
    【解决方案3】:

    FULL OUTER JOIN 将在每个表中有多行时创建有趣的结果集。解决这个问题的更好方法是使用union allrow_number()group by

    select mobnum,
           max(visitedUS) as visitedUS,
           max(visitedUK) as visitedUK,
           max(visitedChina) as visitedChina
    from ((select mobnum, visitedUS, null as visitedUS, null as visitedChina,
                  row_number() over (partition by mobnum order by visitedUS) as seqnum
           from table1
          ) union all
          (select mobnum, null as visitedUS, visitedUK, null as visitedChina,
                  row_number() over (partition by mobnum order by visitedUK) as seqnum
           from table2
          ) union all
          (select mobnum, null as visitedUS, null as visitedUK, visitedChina,
                  row_number() over (partition by mobnum order by visitedChina) as seqnum
           from table1
          )
         ) v
    group by mobnum, seqnum;
    

    【讨论】:

      【解决方案4】:

      我没有测试或仔细检查拼写/语法:

      select 
          isnull(t1.mobnum,isnull(t2.mobnum,t3.mobnum)) mobnum,
          t1.visitedUS, 
          t2.visitedUK, 
          t3.visitedChina
      from Table1 t1
      full outer join Table2 t2 on t1.mobnum = t2.mobnum
      full outer join Table3 t3 on t3.mobnum = isnull(t1.mobnum,t2.mobnum)
      

      【讨论】:

        【解决方案5】:
        CREATE TABLE [dbo].[Table1](
            [mobnum] [bigint] NULL,
            [visitedUS] [date] NULL
        ) ON [PRIMARY]
        GO
        
        CREATE TABLE [dbo].[Table2](
            [mobnum] [bigint] NULL,
            [visitedUK] [date] NULL
        ) ON [PRIMARY]
        
        CREATE TABLE [dbo].[Table3](
            [mobnum] [bigint] NULL,
            [visitedChina] [date] NULL
        ) ON [PRIMARY]
        GO
        INSERT [dbo].[Table1] ([mobnum], [visitedUS]) VALUES (9000000001, CAST(N'2018-10-20' AS Date))
        GO
        INSERT [dbo].[Table1] ([mobnum], [visitedUS]) VALUES (9000000002, CAST(N'2018-10-30' AS Date))
        GO
        INSERT [dbo].[Table2] ([mobnum], [visitedUK]) VALUES (9000000001, CAST(N'2018-11-10' AS Date))
        GO
        INSERT [dbo].[Table2] ([mobnum], [visitedUK]) VALUES (9000000003, CAST(N'2018-11-25' AS Date))
        GO
        INSERT [dbo].[Table3] ([mobnum], [visitedChina]) VALUES (9000000001, CAST(N'2018-12-01' AS Date))
        GO
        INSERT [dbo].[Table3] ([mobnum], [visitedChina]) VALUES (9000000004, CAST(N'2018-12-10' AS Date))
        GO
        

        现在检查以下查询

        SELECT ISNULL(t1.mobnum, ISNULL(t2.mobnum, t3.mobnum)) mobnum,
               t1.visitedUS,
               t2.visitedUK,
               t3.visitedChina
        FROM Table1 t1
            FULL OUTER JOIN Table2 t2
                ON t1.mobnum = t2.mobnum
            FULL OUTER JOIN Table3 t3
                ON t3.mobnum = ISNULL(t1.mobnum, t2.mobnum);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-17
          • 1970-01-01
          • 2016-03-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多