从历史表中检索没有时间戳的姓氏

时间:2018-09-20 14:10:12

标签: sql sql-server tsql

我有以下两个表:

客户:

|Customer Code|Current Customer Code|
|123456|-|
---------------
|123455|-|
---------------
|123454|-|
---------------
|123453|-|
---------------

历史:

|customer Code x (current)|Customer Code y(former)|
|123456|123455|
---------------
|123455|123454|
---------------
|123454|123453|
---------------
|123453|123452|
---------------
|123452|      |

我想要什么:

|Customer Code|Current Customer Code|

|123456|123456|
---------------
|123455|123456|
---------------
|123454|123456|
---------------
|123453|123456|
---------------

目前,customer表中的当前客户未知。我需要从历史记录表中检索当前客户代码,并将其写入客户表中的当前客户字段。

我到这为止:

SELECT 
[Customer Code], [Current Customer Code] FROM customers
LEFT JOIN(
    SELECT 
    c.[Customer Code],
    t.dats
    FROM Customers c
        inner JOIN (
            SELECT [Customer Code x], [Customer Code y] FROM 
            history t
            LEFT JOIN Customers c
            ON t.bpid = c.[customer code]
       ) t
   ON c.[Customer Code] = t.[Customer Code]

一些注意事项:

  • 可以有多组客户,但是这些组将在历史记录表中。
  • 数字可能会有跳跃,例如从12455到12453。

2 个答案:

答案 0 :(得分:1)

[[已更新答案-用于考虑OP修改后的源数据]]

@PreQL提到将数据视为层次结构。

为了方便查询的剪切/粘贴/测试,我在这里声明了几个表变量。

declare @customers TABLE (CustomerCode int, CurrenctCustomerCode int)

insert into @customers values (123456, null)
insert into @customers values (123455, null)
insert into @customers values (123454, null)
insert into @customers values (123453, null)

declare @history TABLE (CustomerCodeX int, CustomerCodeY int)

insert into @history values (123456, 123455)
insert into @history values (123455, 123454)
insert into @history values (123454, 123453)
insert into @history values (123453, 123452)
insert into @history values (123452, null)

我们需要找到层次结构的锚点-并可以通过子查询来完成此操作,该子查询可以找到不是后续贸易ID的“先前” ID的贸易ID。

   select c.* 
     from @customers c 
left join @history h 
       on c.CustomerCode = h.CustomerCodeY  
    where h.CustomerCodeX is null

将带有的子查询放入我的原始CTE中,如下所示:

; with cte (CCX, CCY, CCC) 
as
(

    select h1.CustomerCodeX, h1.CustomerCodeY, x.CustomerCode
    from @history h1
    join (select c.* from @customers c left join @history h on c.CustomerCode = h.CustomerCodeY  where h.CustomerCodeX is null) x
    on h1.CustomerCodeX = x.CustomerCode
    union all 
    select 
        h.CustomerCodeX,
        h.CustomerCodeY,
        cte.CCC
    from @history h
    join cte on h.CustomerCodeX = cte.CCY
)
select CCX as CustomerCode, CCC as CurrentCustomerCode from cte

输出:

CustomerCode CurrentCustomerCode
------------ -------------------
123456       123456
123455       123456
123454       123456
123453       123456
123452       123456

希望它有用。

答案 1 :(得分:0)

您可以使用递归CTE来做到这一点。

我的查询从历史记录中没有新客户代码的所有实际客户代码开始。然后,它使用历史记录(空的记录除外)递归添加以前的客户代码。

WITH
  cte (FormerCustomerCode, CurrenctCustomerCode) AS (
    SELECT actual.CustomerCode, actual.CustomerCode
    FROM customers actual
      LEFT JOIN history newer ON actual.CustomerCode = newer.CustomerCodeY
    WHERE newer.CustomerCodeY IS NULL

    UNION ALL

    SELECT older.CustomerCodeY, newer.CurrenctCustomerCode
    FROM cte newer
      INNER JOIN history older ON newer.FormerCustomerCode = older.CustomerCodeX
    WHERE older.CustomerCodeY IS NOT NULL
  )
UPDATE customers
  SET CurrenctCustomerCode = cte.CurrenctCustomerCode
FROM customers c
  INNER JOIN cte ON c.CustomerCode = cte.FormerCustomerCode;

递归CTE创建如下列表:

CTE Result

然后,UPDATE语句使用此列表来更新客户表(如果需要,请调整MAXRECURSION选项)。