【问题标题】:Retrieving last customer name from history table with no timestamp从没有时间戳的历史表中检索最后一个客户名称
【发布时间】:2018-09-20 14:10:12
【问题描述】:

我有以下两张表:

客户:

|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|
---------------

此时当前客户在客户表中是未知的。我需要从历史表中检索当前客户代码并将其写入客户表中的当前客户字段。

我到此为止:

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。

【问题讨论】:

  • Here 是一个很好的起点。我完全不明白你要做什么。
  • 在查看历史记录的同时从历史记录表中检索最新的当前客户。所以客户的当前客户代码是 123456。而客户代码的历史可以追溯到 123453。在我的客户表中,我想将当前客户代码的值设置为这些客户历史的最新客户代码(在例如:123456 到 123453)
  • 太好了。没有一些细节我无能为力。从您发布的信息来看,我认为您没有太多机会,因为您没有发布任何数据来表明当前客户可能是什么。发布一些表定义和示例数据。然后试着解释你想要什么。
  • 您要检索单个客户还是多个客户?另外,如果你从一个数字开始,预期的结果是什么?另一个号码?请举例?
  • 表格没有自然顺序,所以没有最后一个。

标签: sql sql-server tsql


【解决方案1】:

[[ANSWER UPDATED - 考虑到 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

希望有用。

【讨论】:

  • 哈哈哈,我刚回到家就开始处理这个问题。这正是我要发布的内容:p,+1
  • 我在想这样的事情!我只是没有到达那里的知识/技能。我将尝试看看它是否适用于完整的数据集。
  • 哦不...我弄错了历史表。对不起。我在问题中更新了它。显然,没有客户代码和当前客户代码相同的情况。
  • @PreQL - 抱歉抢了你的风头;-)
  • 哈哈哈,没问题,cmets和答案都是公平的:p
【解决方案2】:

您可以使用递归 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 创建如下列表:

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

【讨论】:

  • 哦不...我弄错了历史记录表。对不起。我在问题中更新了它。显然,没有客户代码和当前客户代码相同的情况。
  • 您的示例历史记录中的第一行仍然相同(将代码映射到自身),现在您似乎更改了新旧客户代码(X 和 Y)的顺序。历史记录中哪个是旧的,哪个是新的客户代码?请再次更新问题。
  • 对不起,为此,再次更新了问题。第一列是当前的,最后一列是以前的。
  • 谢谢,现在我可以稍微缩短我的回答了。 :-)
猜你喜欢
  • 2020-09-22
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多