在 multi-table 连接中允许空值/重复数据删除? T-SQL

Allow nulls / de-duplicate within multi-table join? T-SQL

我想知道在 SSIS 或 T-SQL(SQL Server 2012)中是否有一种方法可以在执行多 return 时轻松地 return 非重复数据=45=] 加入(每列,而不是每行)

我正在尝试对一堆数据进行非规范化/扁平化处理,以便将其转换为仓库,但我最终复制了大量数据。我希望有一种我缺少的 rollup/summary 功能或设计概念可以帮助我将多个 table 合并到一个目的地。

例子

例如,假设我有三个 table:CUSTOMERS、CUSTOMER_ADDRESSES 和 CUSTOMER_ACCOUNTS。他们和他们的数据如下所示:

CUSTOMERS

CUST_ID   NAME
1         Burton Guster

CUSTOMER_ADDRESSES

CUST_ID   ADDR_SEQ    ADDRESS
1         1           123 Awesome St
1         2           456 Fake St

CUSTOMER_ACCOUNTS

CUST_ID   ACCT_SEQ    ACCT_TYPE    ACCOUNT_OPEN_DT
1         1           TAP          1/1/1989
1         2           PHARMA       1/1/2010

我使用这样的查询加入他们:

SELECT a.CUST_ID, a.NAME, b.ADDRESS, c.ACCT_TYPE, c.ACCOUNT_OPEN_DT
FROM CUSTOMERS a
JOIN CUSTOMER_ADDRESSES b on a.CUST_ID = b.CUST_ID
JOIN CUSTOMER_ACCOUNTS c on a.CUST_ID = c.CUST_ID

显然每一行都连接到每一行,正如预期的那样,我的输出如下所示:

ID  NAME            ADDRESS         ACCT_TYPE   ACCT_OPEN_DT
1   Burton Guster   123 Awesome St  TAP         1/1/1989
1   Burton Guster   123 Awesome St  PHARMA      1/1/2010
1   Burton Guster   456 Fake St     TAP         1/1/1989
1   Burton Guster   456 Fake St     PHARMA      1/1/2010

有没有办法让我得到这样的东西?:

ID  NAME            ADDRESS         ACCT_TYPE   ACCT_OPEN_DT
1   Burton Guster   123 Awesome St  TAP         1/1/1989
1   NULL            456 Fake St     PHARMA      1/1/2010

目标是对每一列进行分组,return每列的不同值只计算一次。较大的一组将按客户 ID 分组。

谢谢

当然可以,虽然做起来有点尴尬...:-)

您可以使用 ROW_NUMBER() 从每个 table 独立获得每个客户的 运行 行号。然后您可以使用这些行号将数据放在一起:

;WITH custCTE AS (
  SELECT CUST_ID, NAME, 1 AS CUST_ROW_N
  FROM CUSTOMERS
),
addrCTE AS (
  SELECT CUST_ID, ADDRESS, ROW_NUMBER() OVER(PARTITION BY CUST_ID ORDER BY ADDR_SEQ) CUST_ROW_N
  FROM CUSTOMER_ADDRESSES
),
acctCTE AS (
  SELECT CUST_ID, ACCT_TYPE, ACCOUNT_OPEN_DT, ROW_NUMBER() OVER(PARTITION BY CUST_ID ORDER BY ACCT_SEQ) CUST_ROW_N
  FROM CUSTOMER_ACCOUNTS
)
SELECT COALESCE(a.CUST_ID, b.CUST_ID, c.CUST_ID), a.NAME, b.ADDRESS, c.ACCT_TYPE, c.ACCOUNT_OPEN_DT
FROM custCTE a FULL JOIN addrCTE b ON
  a.CUST_ID = b.CUST_ID AND a.CUST_ROW_N = b.CUST_ROW_N FULL JOIN acctCTE c ON
  (b.CUST_ID = c.CUST_ID AND b.CUST_ROW_N = c.CUST_ROW_N) OR (a.CUST_ID = c.CUST_ID AND a.CUST_ROW_N = c.CUST_ROW_N)

这是一个SQLFiddle