代码之家  ›  专栏  ›  技术社区  ›  KenD Abbas Hadavandi

基于列数据重新排列SQL列并消除重复

  •  2
  • KenD Abbas Hadavandi  · 技术社区  · 11 年前

    对不起,我知道这是一个垃圾标题,但我想不出更简洁的方式来描述这个问题。

    我有一个(MSSQL 2008)表,其中包含电话号码:

     | CustomerID | Tel1     | Tel2      | Tel3     | Tel4     | Tel5      | Tel6   |
     | Cust001    | 01222222 | 012333333 | 07111111 | 07222222 | 01222222  | NULL   |
     | Cust002    | 07444444 | 015333333 | 07555555 | 07555555 | NULL      | NULL   |
     | Cust003    | 01333333 | 017777777 | 07888888 | 07011111 | 016666666 | 013333 |
    

    我想:

    • 删除任何重复的电话号码

    • 重新排列电话号码,使任何以“07”开头的号码都是第一个电话号码。如果有多个07,它们应该在第一个字段中。除此之外,数字的顺序其实并不重要。

    因此,例如,经过处理后,该表将如下所示:

     | CustomerID | Tel1     | Tel2      | Tel3      | Tel4      | Tel5     | Tel6      |
     | Cust001    | 07111111 | 07222222  | 01222222  | 012333333 | NULL     | NULL      |
     | Cust002    | 07444444 | 07555555  | 015333333 | NULL      | NULL     | NULL      |
     | Cust003    | 07888888 | 07011111  | 016666666 | 013333    | 01333333 | 017777777 |
    

    我正在努力想办法有效地实现我的目标(表中有60多万条记录)。有人能帮忙吗?

    我创建了一个 fiddle 如果它能帮助任何人处理这个场景。

    2 回复  |  直到 11 年前
        1
  •  3
  •   RichardTheKiwi    11 年前

    您可以使用UNPIVOT将数字分解为单独的行,然后使用ROW_NUMBER()根据“07”前缀的出现对其进行重新排序,最后使用PIVOT重新组合,以6结尾 Tel 列。

    select *
      FROM
      (
        select CustomerID, Col, Tel
          FROM
          (
            select *, Col='Tel' + RIGHT(
                   row_number() over (partition by CustomerID
                                      order by case
                                             when Tel like '07%' then 1
                                             else 2
                                             end),10)
             from phonenumbers
             UNPIVOT (Tel for Seq in (Tel1,Tel2,Tel3,Tel4,Tel5,Tel6)) seqs
          ) U
      ) P
      PIVOT (MAX(TEL) for Col IN (Tel1,Tel2,Tel3,Tel4,Tel5,Tel6)) V;
    

    SQL Fiddle

        2
  •  -1
  •   AKB    11 年前

    也许使用游标来收集所有客户id并对字段进行排序。。。传统的排序技术,就像我们在学校c++中所做的那样。。哈哈。。。想知道是否有其他可能的方法。

    如果你没有得到,那就是最后一条路了。这将需要很长时间才能确保执行。