2016-10-10 22 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,'-+') 
;