2016-10-10 12 views
0
  • この課題のモチベーションは、特定の方法でお互いに関連するIP範囲のデータセットを簡単かつ正確にシミュレートすることでした。

チャレンジ

テーブルは、テキスト型の単一の列を含んでいます。 テキストには1つ以上の行が含まれ、各行にはダッシュで作成された1つ以上のセクションが含まれます。 目的は、開始点と終了点を持つ各セクションのタプルを返すクエリを記述することです。SQLチャレンジ/パズル:ASCIIアートレンジをリレーショナルデータに変換する方法は?

など。

' 
--- -- - 
---- 
' 
  • 上記のテキストは2行が含まれています。
  • 4つのセクションが含まれています。
  • 最初の行には3つのセクションがあります。
  • 2行目には1セクションが含まれています。
  • 1行目のタプルは(1,3)、(5,6)、(8,8)です。
  • 2行目のタプルは(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

この挑戦は私が対処する実際の人生の挑戦に基づいている仕事中である。それは実用的価値と学習価値の両方を持っているため、ここに掲載されます。私は、Q&Aとしてそれを掲示が、挑戦としてそれを投稿して独自のバージョンと洞察を提示するために他人を奨励していた可能性があります。 –

+0

あなたのいくつかは明らかにパズル/課題の概念を好きではないが、他の人がやることを心に留めておいてください。あなたはhttp://stackoverflow.com/questions/39936479/sql-puzzle-given-a-stack-trace-how-to-find-the-top-element-at-each-point-を見てみましょう場合あなたはゴードン・リノフとマーティン・スミス(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,'-+') 
; 
関連する問題