【问题标题】:SQL Server : joining/ merging tablesSQL Server:加入/合并表
【发布时间】:2021-10-09 08:56:39
【问题描述】:

假设共有三个表 A、B 和 C

每个表都包含以下属性:

  • 表 A:“日期”、“id”、“tv_sales_amt”
  • 表 B:“日期”、“id”、“newspaper_sales_amt”
  • 表 C:“日期”、“id”、“radio_sales_amt”

使用连接运算符,我试图通过以下方式实现单个表视图:

结果表:

"date", "id", "tv_sales_amt", "newspaper_sales_amt", "radio_sales_amt"

结果表的期望外观:

date       id    tv_sales_amt  newspaper_sales_amt   radio_sales_amt 
--------------------------------------------------------------------
20190101   012C     2000             1850            NULL 
20190102   102D     1000             NULL            1300 
.
.
.

以下是我尝试过的一些查询:

查询 #1:

SELECT 
    A.date, A.id, tv_sales_amt, newspaper_sales_amt, radio_sales_amt 
FROM A 
INNER JOIN B ON A.id = B.id 
INNER JOIN C ON A.id = C.id 

使用内部内部连接,我得到重复的值,这是可以理解的,但不是我想要的。

查询 #2:

SELECT 
    A.date, A.id, tv_sales_amt, newspaper_sales_amt, radio_sales_amt 
FROM A 
FULL OUTER JOIN B ON A.id = B.id 
FULL OUTER JOIN C ON A.id = C.id 

由于内连接只会返回与表 A 相交的表 B 和 C(newspaper_sales_amt 和 radio_sales_amt)的结果,因此我尝试了全外连接,希望它能给我提供整个结果的概览,即使它包括空值。

使用我尝试过的两个选项,我都无法获得预期的结果(上面描述的所需外观)。

有人能告诉我我在这里做错了什么吗?

我使用的是最新版本的 SQL Server Management Studio。

我知道,如果我要对tv_sales_amtnewspapers_sales_amtradio_sales_amt 进行概述,肯定会有很多空值,但目前没有空值,但有重复。

【问题讨论】:

标签: sql sql-server tsql


【解决方案1】:

您的描述暗示日期也应该是连接的一部分。

select coalesce(a.date, b.date, c.date) [date],
   coalesce(a.id, b.id, c.id) id, 
   a.tv_sales_amt, b.newspaper_sales_amt, c.radio_sales_amt
from tableA a
full join tableB b on a.id = b.id and a.date = b.date
full join tableC c on (c.id = b.id and c.date = b.date) or 
                      (c.id = a.id and c.date = a.date);

编辑:这是DbFiddle demo. 尝试删除日期或 ID 的 coalesce()(仅删除其中一个有助于更好地查看它)。

编辑:也许这更好地表明了对 coalesce() 的需求:

select coalesce(a.date, b.date, c.date) [date],
   a.id idA, b.id idB, c.id idC, 
   a.tv_sales_amt, b.newspaper_sales_amt, c.radio_sales_amt
from tableA a
full join tableB b on a.id = b.id and a.date = b.date
full join tableC c on (c.id = b.id and c.date = b.date) or 
                      (c.id = a.id and c.date = a.date);

【讨论】:

  • 这正是我想要的!添加日期作为完全加入的约束,我得到了我期望的结果,这非常有帮助。虽然我可能需要做更多的背景搜索来了解合并运算符的实际作用!
  • Coalesce(v1, v2, ... vN) 采用其给定参数的第一个非 NULL 值。之所以存在,是因为 tableA、B 或 C 中的 date 或 id 可能为 null。我将添加一个演示。
  • 非常感谢!这帮助很大。
【解决方案2】:

完全外连接很棘手。我建议:

SELECT COALESCE(A.DATE, B.DATE, C.DATE) as date,
       COALESCE(A.ID, B.ID, C.ID) as id,       
       A.tv_sales_amt, B.newspaper_sales_amt, C.radio_sales_amt 
FROM A FULL JOIN
     B
     ON B.id = A.id AND
        B.date = A.date FULL JOIN
     C
     ON C.id = COALESCE(A.id, B.id) AND
        C.date = COALESCE(B.date, B.date);

我发现在ON 子句中使用COALESCE() 可以简化添加更多条件的过程。从性能的角度来看,COALESCE()OR 都非常糟糕。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    相关资源
    最近更新 更多