SQL将字符串拆分为每行一个字母

时间:2016-08-02 07:33:27

标签: sql string oracle split

我有从表中获取字符串的情况,将其拆分为字母,每个字母代表“活动/非活动”“0/1”,然后从其他表返回描述,仅用于所有活动字母IN ONE CELL .. 注意:字母顺序在其他表格中。

这是我的情况:

CREATE TABLE Strings_tab
(
   Str_id     NUMBER,
   Str_text   VARCHAR2 (40)
);

CREATE TABLE Reprsnt_Tab
(
   rep_id     NUMBER,
   rep_text   VARCHAR2 (40)
);

INSERT INTO Strings_tab VALUES (1, '1111111111000000000011111111110000000000');
INSERT INTO Strings_tab VALUES (2, '0000011111000001111100000111110000011111');

INSERT INTO Reprsnt_Tab VALUES (1, 'rep1');
INSERT INTO Reprsnt_Tab VALUES (2, 'rep2');
INSERT INTO Reprsnt_Tab VALUES (3, 'rep3');   
INSERT INTO Reprsnt_Tab VALUES (4, 'rep4');
INSERT INTO Reprsnt_Tab VALUES (5, 'rep5');
INSERT INTO Reprsnt_Tab VALUES (6, 'rep6');
INSERT INTO Reprsnt_Tab VALUES (7, 'rep7');
INSERT INTO Reprsnt_Tab VALUES (8, 'rep8');
INSERT INTO Reprsnt_Tab VALUES (9, 'rep9');
INSERT INTO Reprsnt_Tab VALUES (10, 'rep10');
INSERT INTO Reprsnt_Tab VALUES (11, 'rep11');
INSERT INTO Reprsnt_Tab VALUES (12, 'rep12');
INSERT INTO Reprsnt_Tab VALUES (13, 'rep13');
INSERT INTO Reprsnt_Tab VALUES (14, 'rep14');
INSERT INTO Reprsnt_Tab VALUES (15, 'rep15');
INSERT INTO Reprsnt_Tab VALUES (16, 'rep16');
INSERT INTO Reprsnt_Tab VALUES (17, 'rep17');
INSERT INTO Reprsnt_Tab VALUES (18, 'rep18');
INSERT INTO Reprsnt_Tab VALUES (19, 'rep19');
INSERT INTO Reprsnt_Tab VALUES (20, 'rep20');
INSERT INTO Reprsnt_Tab VALUES (21, 'rep21');
INSERT INTO Reprsnt_Tab VALUES (22, 'rep22');
INSERT INTO Reprsnt_Tab VALUES (23, 'rep23'); 
INSERT INTO Reprsnt_Tab VALUES (24, 'rep24');
INSERT INTO Reprsnt_Tab VALUES (25, 'rep25');
INSERT INTO Reprsnt_Tab VALUES (26, 'rep26');
INSERT INTO Reprsnt_Tab VALUES (27, 'rep27');
INSERT INTO Reprsnt_Tab VALUES (28, 'rep28');
INSERT INTO Reprsnt_Tab VALUES (29, 'rep29');
INSERT INTO Reprsnt_Tab VALUES (30, 'rep30');
INSERT INTO Reprsnt_Tab VALUES (31, 'rep31');
INSERT INTO Reprsnt_Tab VALUES (32, 'rep32');
INSERT INTO Reprsnt_Tab VALUES (33, 'rep33');
INSERT INTO Reprsnt_Tab VALUES (34, 'rep34');
INSERT INTO Reprsnt_Tab VALUES (35, 'rep35');
INSERT INTO Reprsnt_Tab VALUES (36, 'rep36');
INSERT INTO Reprsnt_Tab VALUES (37, 'rep37');
INSERT INTO Reprsnt_Tab VALUES (38, 'rep38');
INSERT INTO Reprsnt_Tab VALUES (39, 'rep39');  
INSERT INTO Reprsnt_Tab VALUES (40, 'rep40');

COMMIT;

这是我的疑问:

SELECT STR_TEXT,
       RTRIM (
          XMLAGG (XMLELEMENT (E, DATA.REP_TEXT || ',' || CHR (10))).EXTRACT (
             '//text()'),
          ',')
          REPS
  FROM (  SELECT LETTER,
                 STR_ID,
                 LVL,
                 STR_TEXT,
                 REP_TEXT
            FROM (    SELECT DISTINCT SUBSTR (A.STR_TEXT, LEVEL, 1) LETTER,
                                      A.STR_ID,
                                      LEVEL LVL,
                                      A.STR_TEXT
                        FROM STRINGS_TAB A
                  CONNECT BY LEVEL <= LENGTH (A.STR_TEXT) ---- HERE IS MY PROBLEM
                                        ) TXT,
                 (  SELECT ROWNUM RN, REPRSNT_TAB.*
                      FROM REPRSNT_TAB
                  ORDER BY REP_ID) B
           WHERE B.RN = TXT.LVL AND LETTER = 1
        ORDER BY STR_ID, STR_TEXT, LVL) DATA
        GROUP BY STR_TEXT

此查询获取正确的数据 如果我用10代替“LENGTH(A.STR_TEXT)”来获得每个字符串的前10个字母。 但是..如果“LENGTH(A.STR_TEXT)”如此之大,在我的情况下40,查询将挂起 所以,请告诉我..在这种情况下???

来自我的查询的结果,如果我把“LEVEL&lt; = 10”:

       STR_TEXT                         REP
------------------------------- ------------------------------
000001111100000111110000011111  rep6,rep10,rep9,rep8,rep7
111111111100000000001111111111  rep1,rep10,rep9,rep8,rep7,rep6,rep5,rep4,rep3,rep2

3 个答案:

答案 0 :(得分:1)

我的方法将CONNECT BY LEVEL带到一个辅助表(在一个表中使用with aux as (select level as lvl from dual connect by level <= (select max(length(str_text)) from strings_tab)) SELECT STR_TEXT, RTRIM ( XMLAGG (XMLELEMENT (E, DATA.REP_TEXT || ',' || CHR (10))).EXTRACT ( '//text()'), ',') REPS FROM ( SELECT LETTER, STR_ID, LVL, STR_TEXT, REP_TEXT FROM ( SELECT DISTINCT SUBSTR (A.STR_TEXT, LVL, 1) LETTER, A.STR_ID, LVL, A.STR_TEXT FROM STRINGS_TAB A join aux x on x.lvl <=LENGTH (A.STR_TEXT) ) TXT, ( SELECT ROWNUM RN, REPRSNT_TAB.* FROM REPRSNT_TAB ORDER BY REP_ID) B WHERE B.RN = TXT.LVL AND LETTER = 1 ORDER BY STR_ID, STR_TEXT, LVL) DATA GROUP BY STR_TEXT; 超过1行不是一个好主意恕我直言。看看here):

STR_TEXT                                    REPS
0000011111000001111100000111110000011111    rep6,rep40,rep39,rep38,rep37,rep36,rep30,rep29,rep28,rep27,rep26,rep20,rep19,rep18,rep17,rep16,rep10,rep9,rep8,rep7
1111111111000000000011111111110000000000    rep1,rep30,rep29,rep28,rep27,rep26,rep25,rep24,rep23,rep22,rep21,rep10,rep9,rep8,rep7,rep6,rep5,rep4,rep3,rep2

输出(没有(CHAR(10))

 using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        using (StreamReader responseReader = new StreamReader(responseStream))
                        {
                            string json = responseReader.ReadToEnd();
                            string data = JObject.Parse(json)["id"].ToString();
                        }
                    }
                }

//json = {"kind": "ALL", "id": "1221455", "longUrl": "NewURL"}

答案 1 :(得分:0)

这是我的答案:

  SELECT str_text,
         LISTAGG (DATA.REP_TEXT, ',' || CHR (10))
            WITHIN GROUP (ORDER BY DATA.rn_rep)
            reps
    FROM (SELECT *
            FROM (  SELECT str_text, SUBSTR (str_text, rn, 1) OneDigit, rn
                      FROM (SELECT str_text FROM STRINGS_TAB) txt,
                           (    SELECT ROWNUM rn
                                  FROM DUAL
                            CONNECT BY LEVEL <=
                                          (SELECT MAX (LENGTH (str_text))
                                             FROM STRINGS_TAB)) rep
                     WHERE REP.RN <= LENGTH(str_text)
                  ORDER BY Str_text, rn) xx,
                 (  SELECT ROWNUM rn_rep, rep_text
                      FROM REPRSNT_TAB
                  ORDER BY rn_rep) desc_rep
           WHERE desc_rep.rn_rep = xx.rn AND OneDigit = 1) data
GROUP BY str_text

答案 2 :(得分:0)

select Str_id
      ,Str_text
      ,xmlquery('let $abc :=  for $i in 1 to string-length($str) 
                              where substring($str, $i, 1) = "1" 
                                   return $data/rows/row[$i]/text() 
                    return  string-join( $abc, ",")' 
        passing   Str_text as "str"
              , (select xmlelement("rows",xmlagg(xmlelement( "row",rep_text)  order by rep_id)) from Reprsnt_Tab) as "data" 
       returning content
     ) from Strings_tab

表Reprsnt_Tab聚合为一个xmlelemtnt。要访问所选行,您只需执行$doc/rows/row[$selected_row_nr]/text()