【问题标题】:create a table of duplicated rows of another table using the select statement使用 select 语句创建另一个表的重复行的表
【发布时间】:2014-07-04 05:10:00
【问题描述】:

我有一个表,其中一列包含不同的整数。
对于表中的每个整数,我想将其复制为位数 - 例如:

12345(5 位数):
1. 12345
2. 12345
3. 12345
4. 12345
5. 12345

我想用with recursion t (...) as () 来做这件事,但我没能做到,因为我真的不明白它是如何工作的,以及“幕后发生的事情”。
我不想使用insert,因为我希望它可以根据表中的需要对尽可能多的整数进行扩展和自动处理。
任何想法和解释都会很棒。

【问题讨论】:

  • 在您的示例中,您想创建 5 行具有相同值 12345?你需要1./2./3./4./5吗?作为一个新的专栏,也是?还是这只是一种行号?
  • 我真的不需要新列,只需要数字本身。
  • 再问一个问题:您为什么需要它?我无法想象任何现实世界的场景......

标签: sql select teradata


【解决方案1】:

最简单的方法是加入一个包含从 1 到 n 的数字的表。

SELECT n, x
FROM yourtable
JOIN
 (
   SELECT day_of_calendar AS n 
   FROM sys_calendar.CALENDAR
   WHERE n BETWEEN 1 AND 12 -- maximum number of digits 
 ) AS dt
ON n <= CHAR_LENGTH(TRIM(ABS(x)))

在我的示例中,我滥用了 TD 的内置日历,但这不是一个好的选择,因为优化器不知道将返回多少行,而且计划必须是 Product Join,它可能会决定做一些愚蠢的事情。所以最好使用数字表...

【讨论】:

    【解决方案2】:

    创建一个数字表,其中包含从 1 到表中数字的最大位数(我选择 6)的整数:

    create table numbers(num int)
    insert numbers
    select 1 union select 2 union select 3 union select 4 union select 5 union select 6
    

    你已经有了你的桌子(但这是我用来测试的):

    create table your_table(num int)
    insert your_table
    select 12345 union select 678   
    

    这是获取结果的查询:

    select ROW_NUMBER() over(partition by b.num order by b.num) row_num, b.num, LEN(cast(b.num as char)) num_digits
    into #temp
    from your_table b
    cross join numbers n    
    
    select t.num
    from #temp t
    where t.row_num <= t.num_digits
    

    【讨论】:

      【解决方案3】:

      我找到了一种执行此操作的好方法。这里是:

      with recursive t (num,num_as_char,char_n)
      as 
      (
          select   num
                  ,cast (num as varchar (100)) as num_as_char
                  ,substr (num_as_char,1,1)   
      
          from    numbers
      
          union all 
      
          select   num
                  ,substr (t.num_as_char,2) as num_as_char2
                  ,substr (num_as_char2,1,1)  
      
          from    t       
      
          where   char_length (num_as_char2) > 0
      )
      
      select  *
      from    t
      order by num,char_length (num_as_char) desc
      

      【讨论】:

        猜你喜欢
        • 2020-08-05
        • 1970-01-01
        • 1970-01-01
        • 2014-01-20
        • 2021-01-08
        • 2013-12-21
        • 2017-06-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多