|
■No97160 (魔界の仮面弁士) に追記
>> 関数を作らない方法はないということでしょうか?
> 関数無しで実装するなら、共通テーブル式で再帰問い合わせをして、
> STRING_AGG 関数あるいは FOR XML PATH 式で連結するとか。
こんな感じかな…。
手元に環境が無いので未検証です。
-- サンプルデータ
CREATE TABLE Sample
(id int PRIMARY KEY, text nvarchar(100) NULL);
INSERT INTO Sample VALUES
(1, '001002003004005')
,(2, '003004005006007')
,(3, '003004003004003')
,(4, '1234567')
,(5, '')
,(6, NULL)
;
-- STRING_AGG 版 --
WITH CTE (id, text, pos, chunk) AS (
SELECT
Sample.id, Sample.text, pos = CAST(1 AS INT), SUBSTRING(Sample.text, 1, 3) AS chunk
FROM
Sample
UNION ALL
SELECT
CTE.id, CTE.text, CTE.pos + 3, SUBSTRING(CTE.text, CTE.pos + 3, 3)
FROM
CTE
WHERE
ISNULL(SUBSTRING(CTE.text, CTE.pos + 3, 3), '') <> ''
)
SELECT
CTE.id
, result = STRING_AGG(chunk, '') WITHIN GROUP (ORDER BY CTE.pos)
FROM
CTE
WHERE
CTE.chunk NOT IN ('003', '004')
GROUP BY
CTE.id
ORDER BY
CTE.id
;
-- FOR XML PATH 版 --
WITH CTE (id, text, pos, chunk) AS (
SELECT
Sample.id, Sample.text, pos = CAST(1 AS INT), SUBSTRING(Sample.text, 1, 3) AS chunk
FROM
Sample
UNION ALL
SELECT
CTE.id, CTE.text, CTE.pos + 3, SUBSTRING(CTE.text, CTE.pos + 3, 3)
FROM
CTE
WHERE
ISNULL(SUBSTRING(CTE.text, CTE.pos + 3, 3), '') <> ''
), CTE2 AS (
SELECT
CTE.id
, CTE.pos
, CTE.chunk
, CTE.text
FROM
CTE
WHERE
ISNULL(CTE.chunk, '') NOT IN ('003', '004')
)
SELECT DISTINCT
CTE2.id
, CTE2.text
, result = (
SELECT CTE3.chunk+''
FROM CTE2 AS CTE3
WHERE CTE3.id = CTE2.id
ORDER BY CTE3.pos
FOR XML PATH('')
)
FROM
CTE2
ORDER BY
CTE2.id
;
|