2016-10-10 21 views
0
  • 这个挑战的动机是以一种特定的方式轻松而准确地模拟IP范围相互关联的数据集。

挑战

一个表包含文本类型的单个列。 该文本包含一行或多行,其中每行包含一个或多个由破折号创建的部分。 目标是编写一个查询,该查询使用其起点和终点为每个部分返回一个元组。SQL挑战/拼图:如何将ASCII艺术范围转换为关系数据?

E.g.

' 
--- -- - 
---- 
' 
  • 文本上述含有2行。
  • 它包含4个部分。
  • 第一行包含3个部分。
  • 第二行包含1个部分。
  • 第一行的元组是(1,3),(5,6),(8,8)。
  • 第二行的元组是(2,5)。

要求
  • 溶液应该是单个SQL查询(子查询都很好)。
  • 使用T-SQL,PL/SQL等不允许
  • 使用UDF(用户定义函数)的不允许

  • 如果需要的话,我们可能会认为,只有在表中的单个记录。

样本数据

create table t (txt varchar (1000) not null); 

insert into t (txt) values 
(
' 
--- --- --- --- 
----------   - 
- - -- -- --- --- 
     ----- ---- --- -- - 
    ------- 
' 
); 

请求的结果

*只有最后2列(section_start /结束)是必需的,其余都是用于调试目的。

line_ind section_ind section_length section_start section_end 
-------- ----------- -------------- ------------- ----------- 
1   1   3    2    4 
1   2   3    6    8 
1   3   3    11    13 
1   4   3    17    19 
2   1   10    1    10 
2   2   1    21    21 
3   1   1    2    2 
3   2   1    4    4 
3   3   2    6    7 
3   4   2    9    10 
3   5   3    12    14 
3   6   3    16    18 
4   1   5    7    11 
4   2   4    13    16 
4   3   3    18    20 
4   4   2    22    23 
4   5   1    25    25 
5   1   7    4    10 
+7

您应该删除,并张贴在这里,而不是:http://codegolf.stackexchange.com/ –

+0

这个挑战是基于我处理的现实生活挑战t在工作中。它在这里发布,因为它具有实用价值和学习价值。我本可以将其作为问答发布,但将其作为挑战发布会鼓励其他人展示自己的版本和见解。 –

+0

尽管你们中有些人显然不喜欢拼图/挑战的概念,但请记住其他人也这样做。如果你看看http://stackoverflow.com/questions/39936479/sql-puzzle-given-a-stack-trace-how-to-find-the-top-element-at-each-point-在这里你会发现Gordon Linoff和Martin Smith,stackoverflow的传奇人物很喜欢它。 –

回答

0

的Teradata

with  l 
      as 
      (
       select  line_ind 
          ,line 

       from  table 
          (
           regexp_split_to_table (-1,t.txt,'\r','') 
           returns (minus_one int,line_ind int,line varchar(1000)) 
          ) 
          as l 
      ) 

select  l.line_ind 
      ,s.section_ind           
      ,regexp_instr (l.line,'\S+',1,s.section_ind,0)  as section_start 
      ,regexp_instr (l.line,'\S+',1,s.section_ind,1) - 1 as section_end 
      ,char_length  (s.section)        as section_length 

from  table 
      (
       regexp_split_to_table (l.line_ind,l.line,'\s+','') 
       returns (line_ind int,section_ind int,section varchar(1000)) 
      ) 
      as s 
      ,l 

where  l.line_ind = 
      s.line_ind 

order by l.line_ind 
      ,s.section_ind 
; 
0

甲骨文

SELECT row_n AS line_ind 
    ,dense_rank() over(PARTITION BY row_n ORDER BY s_beg) AS section_ind 
    ,s_end - s_beg AS section_length 
    ,s_beg - decode(row_n, 0, 0, instr(a,chr(10),1,row_n)) AS section_start 
    ,s_end - decode(row_n, 0, 0, instr(a,chr(10),1,row_n)) -1 AS section_end 
    FROM (SELECT a 
      ,s_beg 
      ,DECODE(s_end, 0, length(a) + 1, s_end) AS s_end 
      ,length(substr(a, 1, s_beg)) 
       - length(REPLACE(substr(a, 1, s_beg), chr(10))) AS row_n 
      ,lvl 
    FROM (SELECT txt as a 
        ,DECODE(LEVEL, 1, 0, regexp_instr(txt , '\s|\n', 1, LEVEL - 1)) + 1 AS s_beg 
        ,regexp_instr(txt , '\s|\n', 1, LEVEL) AS s_end 
        ,LEVEL AS lvl 
      FROM t 
      CONNECT BY LEVEL <= length(txt) - length(regexp_replace(txt , '\s|\n')) + 1) 
    )WHERE s_beg != s_end; 
+0

嗨迈克尔。请将您的结果与请求的结果进行比较。 –

+0

嗨Dudu。谢谢。我修正了ID。 –

0

甲骨文

select  regexp_instr (txt,'-+',1,level,0)  - instr (txt,chr(10),regexp_instr (txt,'-+',1,level,0) - length (txt) - 1,1) as section_start 
      ,regexp_instr (txt,'-+',1,level,1) - 1 - instr (txt,chr(10),regexp_instr (txt,'-+',1,level,0) - length (txt) - 1,1) as section_end 

from  t 

connect by level <= regexp_count (txt,'-+') 
;