SQLパズル:文字列中の重複する文字を削除する
もろに手続き型で解いてみた。
with recursive temp (word_key, idx, word_txt) as ( select word_key, 1 as idx, cast(substring(word_txt from 1 for 1) as varchar(25)) as word_txt from WordList union all select temp.word_key, temp.idx + 1 as idx, case when position(substring(w.word_txt from temp.idx + 1 for 1) in w.word_txt) = temp.idx+1 then temp.word_txt || substring(w.word_txt from temp.idx + 1 for 1) else temp.word_txt end as word_txt from WordList w, temp where w.word_key = temp.word_key and CHARACTER_LENGTH(w.word_txt) > temp.idx ) select x.word_key, x.word_txt from temp x join (select word_key, max(idx) as max_idx from temp group by word_key) as y on x.word_key = y.word_key and x.idx = y.max_idx order by x.word_key
解けたけど、エレガントじゃなさすぎる…。
2008-08-16T01:00:00+9:00追記
MAX使わなくて良い様にフラグにしてみた。
WITH RECURSIVE temp (word_key, idx, word_txt, end_flag) AS ( SELECT word_key, 1 AS idx, CAST(SUBSTRING(word_txt FROM 1 FOR 1) AS VARCHAR(25)) AS word_txt, 0 AS end_flag FROM WordList UNION ALL SELECT temp.word_key, temp.idx + 1 AS idx, CASE WHEN POSITION(SUBSTRING(w.word_txt FROM temp.idx + 1 FOR 1) IN w.word_txt) = temp.idx + 1 THEN temp.word_txt || SUBSTRING(w.word_txt FROM temp.idx + 1 FOR 1) ELSE temp.word_txt END AS word_txt, CASE temp.idx + 1 WHEN CHARACTER_LENGTH(w.word_txt) THEN 1 ELSE 0 END AS end_flag FROM WordList w, temp WHERE w.word_key = temp.word_key AND CHARACTER_LENGTH(w.word_txt) > temp.idx ) SELECT word_key, word_txt FROM temp WHERE end_flag = 1 ORDER BY word_key