Sql server 在最佳密钥上合并遗留数据

Sql server 在最佳密钥上合并遗留数据,sql-server,join,case,databricks,predicate,Sql Server,Join,Case,Databricks,Predicate,我引入了一个来自旧系统的字段,该系统与新表没有主键-外键关系。数据是事务性的,每条线都有一个客户和销售代表 传统字段与客户之间存在多对多关系(但仅在某些情况下),但当您链接客户和销售代表时,该字段变为一对多关系。但是,数据混乱,交易可能与销售代表不完全匹配 似乎解决此问题的最佳方法是尽可能加入customer和sales rep,如果不匹配,则只需加入customer即可 我可以通过以下方式在Excel中执行此操作: =IFERROR(VLOOKUP(Customer_SalesRep_Comb

我引入了一个来自旧系统的字段,该系统与新表没有主键-外键关系。数据是事务性的,每条线都有一个客户和销售代表

传统字段与客户之间存在多对多关系(但仅在某些情况下),但当您链接客户和销售代表时,该字段变为一对多关系。但是,数据混乱,交易可能与销售代表不完全匹配

似乎解决此问题的最佳方法是尽可能加入customer和sales rep,如果不匹配,则只需加入customer即可

我可以通过以下方式在Excel中执行此操作:

=IFERROR(VLOOKUP(Customer_SalesRep_Combo, DataTable, 3, FALSE),VLOOKUP(Customer,Datatable,3,FALSE))
excel中的这个函数可以工作,但电子表格太大,容易崩溃,所以我尝试使用SQL代码复制它

请注意,遗留系统只输出CSV文件,因此我将该CSV上传到云,现在我使用DataRicks将其转换为Spark数据帧,以便在其上使用SQL逻辑

最初,我的想法是使用两个条件(匹配80k行中的50k行)进行左连接,并使用一个条件进行左连接。然后,我将两次引入遗留字段(如果匹配,则两次,如果不匹配,则一次)。然后,如果没有硬匹配,我会使用案例陈述来引入“软匹配”。然而,由于多对多的关系,我会在左侧连接上经历连接重复。由于我也带来了销售数据,我不能有任何重复。然而,如果我能使用第一个匹配并抑制任何重复,我将能够忍受一些不准确的情况

我见过在联接中使用case语句的例子,但我不知道如何在本例中使用它。如果我无法实现这一点,我将求助于迭代数据帧以匹配Scala中的逻辑,但我更喜欢SQL解决方案。 我的代码如下。真实版本包含更多字段,但这是在保留基本逻辑的情况下我能得到的最简单的字段

SELECT 
    InnerQry.Customer,
    InnerQry.SalesRep,
    InnerQry.Sales,
    CASE 
        WHEN InnerQry.LegacyFieldHard IS NULL 
           THEN InnerQry.LegacyFieldSoft
        ELSE InnerQry.LegacyFieldHard
    END AS LegacyField
FROM
    (SELECT 
         A.Customer,
         A.SalesRep, 
         A.Sales,
         B.LegacyFieldHard,
         C.LegacyFieldSoft
     FROM 
         DBS AS A
     LEFT JOIN 
         LEGACY AS B ON A.Customer = B.Customer AND A.SalesRep = B.SalesRep
     LEFT JOIN 
         LEGACY AS C ON A.Customer = B.Customer) AS InnerQry

这里的主要问题是,当您仅基于客户(遗留C)进行映射时,会得到多行。为了避免这种情况,您可以创建一个行号字段并将其限制为1,前提是您并不真正关心该客户记录中的哪一条记录被映射:

SELECT 
    A.Customer,
    A.SalesRep, 
    A.Sales,
    COALESCE(B.LegacyField,C.LegacyField) as LegacyField
FROM DBS AS A
LEFT JOIN LEGACY AS B ON A.Customer=B.Customer AND A.SalesRep=B.SalesRep
LEFT JOIN 
    (select *,
            row_number() Over (partition by Customer order by SalesRep) as rownum1 
    from LEGACY) AS C ON A.Customer=C.Customer and C.rownum1=1

此外,还可以直接使用COALESCE函数,而不是case语句。这将自动使用第一个非空值。i、 e)仅当B为空时,才取C值。希望这有帮助。

当你加入C时,你会得到你想要的和已经匹配的。可能会明确排除这些?例如,在A.Customer=B.Customer和A.SalesRep C.SalesRep上将遗留的连接保留为C。连接逻辑是genius!我从未考虑过只使用第一排。我也不知道凝聚函数。我回到办公室后会测试一下。非常感谢。这个解决方案非常有效。它还帮助我完成了其他几个项目。正在旧系统上合并新系统@CR7SMS