3

私は愚かなテーブルとデータを持っています。私はする必要があります: 1-各行の各文を新しい行に分割します 2-soundex関数に基づいて文の最後の部分に基づいて各行の単語を数えます

create table a (id number(9), words varchar(500));
insert into a values(1,'UK,LONDON,YEMEN,JOHN,CAIRO,OMAR ALI,EGYPT,Cairo,YEMAN,OMAR AMR ALI,LONDAN');
insert into a values(2,'UK,SUDAI,SUDAIN,AYHAM SHAHER YAFOOZ,ALI YAFOOZ');
insert into a values(3,'MALAYSIA, AHMED ALI,MALYSIAN');

期待される出力

テーブル temp_words(id number(9),words varchar2(100), count_words number(9)) を作成します。

id            words                count_words
1              UK                     1
1            LONDON                   2
1            YEMEN                    2
1            CAIRO                    2
1            OMAR ALI                 2
1             JOHN                    1
2              UK                     1
2              SUDAI                  2
2          AYHAM SHAHER YAFOOZ        2
3               MALAYSIA              2
3              AHMED ALI              1

よろしく

4

4 に答える 4

1

必要に応じてデータを分割するには、「接続方法」を行ジェネレーターとして使用できます。

SQL> with src as (select id,',' || words || ',' as words,
  2                      length(words) - length(translate(words, '.,', '.')) + 1 no_of_words
  3                 from a)
  4  select a.id,
  5         substr(a.words,
  6                instr(words, ',', 1, r) + 1,
  7                instr(words, ',', 1, r + 1) - instr(words, ',', 1, r) - 1) word,
  8         a.no_of_words
  9    from (select level r
 10            from dual
 11          connect by level <= (select max(no_of_words) from src)) d
 12         inner join src a
 13                on d.r <= a.no_of_words
 14   where a.no_of_words is not null
 15   order by a.id, d.r
 16  /

        ID WORD                 NO_OF_WORDS
---------- -------------------- -----------
         1 UK                            11
         1 LONDON                        11
         1 YEMEN                         11
         1 JOHN                          11
         1 CAIRO                         11
         1 OMAR ALI                      11
         1 EGYPT                         11
         1 Cairo                         11
         1 YEMAN                         11
         1 OMAR AMR ALI                  11
         1 LONDAN                        11
         2 UK                             5
         2 SUDAI                          5
         2 SUDAIN                         5
         2 AYHAM SHAHER YAFOOZ            5
         2 ALI YAFOOZ                     5
         3 MALAYSIA                       3
         3  AHMED ALI                     3
         3 MALYSIAN                       3

19 rows selected.

SQL>
于 2012-12-10T13:07:50.873 に答える
1

ここにSQLFiddleのデモがあります

select id,words,

case when i=0 then
SUBSTR(words,
   1,
case when INSTR(words,',', 1, 1)=0 
       then 100000
       else
       INSTR(words,',', 1, 1)-1
       end

   )    
ELSE

SUBSTR(words,
   INSTR(words,',', 1, i)+1,

   case when INSTR(words,',', 1, i+1)=0 
       then 100000
       else
       INSTR(words,',', 1, i+1)-INSTR(words,',', 1, i)-1 
       end

   )
END word,
i+1 COUNTWORDS

from a,
(
select * from
(
select 0 i from dual 
union 
select 1 i from dual 
union 
select 2 i from dual 
union 
select 3 i from dual
union 
select 4 i from dual 
union 
select 5 i from dual 
union 
select 6 i from dual
union 
select 7 i from dual
union 
select 8 i from dual
union 
select 9 i from dual
union 
select 10 i from dual
union 
select 11 i from dual
union 
select 12 i from dual
 )
  )
table_i

where 
  case when i>0 then INSTR(words,',', 1, i) 
  else 100000 end <>0 
order by id,i
于 2012-12-10T13:16:43.270 に答える
1

別のアプローチ(regexp_countおよびregexp_substr正規表現関数を使用):

SQL> with Occurence(oc) as(
  2    select level
  3      from ( select max(regexp_count(words, '[^,]+')) ml
  4               from a
  5            ) t
  6     connect by level <= t.ml
  7  )
  8  select id
  9       , word
 10       , count(word) over(partition by id, soundex(word) order by id) as count_words
 11    From ( select a.id
 12                , regexp_substr(words, '[^,]+', 1, o.oc) as word
 13             from occurence o
 14            cross join a
 15          ) s
 16            where s.word is not null
 17  order by id
 18  ;

        ID WORD                 COUNT_WORDS
---------- -------------------- -----------
         1 Cairo                          2
         1 CAIRO                          2
         1 EGYPT                          1
         1 JOHN                           1
         1 LONDAN                         2
         1 LONDON                         2
         1 OMAR ALI                       1
         1 OMAR AMR ALI                   1
         1 UK                             1
         1 YEMEN                          2
         1 YEMAN                          2
         2 ALI YAFOOZ                     1
         2 AYHAM SHAHER YAFOOZ            1
         2 SUDAI                          1
         2 SUDAIN                         1
         2 UK                             1
         3  AHMED ALI                     1
         3 MALAYSIA                       1
         3 MALYSIAN                       1

19 rows selected
于 2012-12-10T13:26:51.423 に答える
0

データを個別のレコードとして挿入する必要があります。必要に応じて、それらを連結された文字列として保持することもできますが、それはあなたの人生を非常に困難にするだけです。それで:

create table words (
  id number,
  w  varchar2(100),
  s  varchar2(4)
);

create or replace trigger words_auto
  before insert or update on words
  for each row
begin
  select trim(upper(:new.w)), soundex(:new.w)
  into   :new.w,              :new.s
  from   dual;
end;

insert into words (id, w) values (1, 'UK');
insert into words (id, w) values (1, 'LONDON');
...
insert into words (id, w) values (3, ' AHMED ALI');
insert into words (id, w) values (3, 'MALYSIAN');

連結された文字列を分割し、wordsテーブルに適切にデータを入力するプロシージャを作成できます。入力を大文字に正規化し、余分な空白をすべて削除して、Soundexコードを自動的に生成するトリガーを作成したことに注意してください。

ここで質問があります。Soundexコードで単語をグループ化する必要があります。ただし、ベースラインをどのように決定しますか?たとえば、「LONDON」と「LONDAN」はどちらもコード「L535」を持っていますが、どちらのレコードが「メイン」のレコードであるかをどうやって知ることができますか?...さらにルックアップテーブルがないとできません!そのため、Soundexコードでグループ化するのが最善の方法です。これはテーブルに保存する必要はなく、ビューである方が理にかなっています。

create or replace view word_counts as
  select   id,
           s soundex,
           count(w) count_rows
  from     words
  group by id,
           s;

count_rows個別の行ではなく、レコードをカウントするため、カウントフィールドを呼び出したことに注意してください。つまり、「LONDON」、「LONDAN」、および「LONDON」のレコードは、2ではなく3のカウントで表示されます(これは予想どおりです)。とにかく、データを使用すると、ビューは次のようになります。

id    soundex   count_rows
----- --------- -----------
1     U200      1
1     L535      2
...   ...       ...
3     M420      2
3     A534      1

私が言うように、それはあなたがそれ以上のインフラストラクチャなしで期待できる本当に最高です。

于 2012-12-10T12:51:23.420 に答える