次のような SQL テーブルがあります:
サムID | その他ID | データ |
---|---|---|
abcdef・・・ | cdef123-... | 18,20,22 |
abcdef・・・ | 4554a24-... | 17,19 |
987654-..... | 12324a2-... | 13,19,20 |
SELECT OtherID, SplitData WHERE SomeID = 'abcdef-.......'
次のように、個々の行を返すクエリを実行できるクエリはありますか?
その他ID | 分割データ |
---|---|
cdef123-... | 18 |
cdef123-... | 20 |
cdef123-... | 22 |
4554a24-... | 17 |
4554a24-... | 19 |
基本的に、データをコンマで個別の行に分割しますか?
文字列をリレーショナル データベースに保存するのは馬鹿げたことのように聞こえますcomma-separated
が、消費者向けアプリケーションの通常の使用例では、それが非常に役立ちます。
ページングが必要なため、アプリケーションを分割したくないので、アプリ全体をリファクタリングする前にオプションを検討したいと考えました。
それはSQL Server 2008
(非R2)です。
ベストアンサー1
SQL Server の優れた再帰関数を使用できます。
サンプルテーブル:
CREATE TABLE Testdata
(
SomeID INT,
OtherID INT,
String VARCHAR(MAX)
);
INSERT Testdata SELECT 1, 9, '18,20,22';
INSERT Testdata SELECT 2, 8, '17,19';
INSERT Testdata SELECT 3, 7, '13,19,20';
INSERT Testdata SELECT 4, 6, '';
INSERT Testdata SELECT 9, 11, '1,2,3,4';
クエリ
WITH tmp(SomeID, OtherID, DataItem, String) AS
(
SELECT
SomeID,
OtherID,
LEFT(String, CHARINDEX(',', String + ',') - 1),
STUFF(String, 1, CHARINDEX(',', String + ','), '')
FROM Testdata
UNION all
SELECT
SomeID,
OtherID,
LEFT(String, CHARINDEX(',', String + ',') - 1),
STUFF(String, 1, CHARINDEX(',', String + ','), '')
FROM tmp
WHERE
String > ''
)
SELECT
SomeID,
OtherID,
DataItem
FROM tmp
ORDER BY SomeID;
-- OPTION (maxrecursion 0)
-- normally recursion is limited to 100. If you know you have very long
-- strings, uncomment the option
出力
SomeID | OtherID | DataItem
--------+---------+----------
1 | 9 | 18
1 | 9 | 20
1 | 9 | 22
2 | 8 | 17
2 | 8 | 19
3 | 7 | 13
3 | 7 | 19
3 | 7 | 20
4 | 6 |
9 | 11 | 1
9 | 11 | 2
9 | 11 | 3
9 | 11 | 4