SQLクエリのヘルプが必要です。値がコンマ区切りの値として格納されている列があります。
列の各値内で3番目に区切られた項目を見つけるクエリを作成する必要があります。
これをSelectステートメントで行うことは可能ですか?例:ColumnValue:josh,Reg01,False,a0-t0,22/09/2010
False
したがって、上記の文字列から3番目の値(つまり)を取得する必要があります。
はい。
あなたのひもはどこ@s
にありますか...
select
SUBSTRING (@s,
CHARINDEX(',',@s,CHARINDEX(',',@s)+1)+1,
CHARINDEX(',',@s,CHARINDEX(',',@s,CHARINDEX(',',@s)+1)+1)
-CHARINDEX(',',@s,CHARINDEX(',',@s)+1)-1)
またはより一般的に...
;with cte as
(
select 1 as Item, 1 as Start, CHARINDEX(',',@s, 1) as Split
union all
select cte.Item+1, cte.Split+1, nullif(CHARINDEX(',',@s, cte.Split+1),0) as Split
from cte
where cte.Split<>0
)
select SUBSTRING(@s, start,isnull(split,len(@s)+1)-start)
from cte
where Item = 3
データを適切に保存します:)
これを試してください(SQL Server 2005以降を想定)
DECLARE @t TABLE(ColumnValue VARCHAR(50))
INSERT INTO @t(ColumnValue) SELECT 'josh,Reg01,False,a0-t0,22/09/2010'
INSERT INTO @t(ColumnValue) SELECT 'mango,apple,bannana,grapes'
INSERT INTO @t(ColumnValue) SELECT 'stackoverflow'
SELECT ThirdValue = splitdata
FROM(
SELECT
Rn = ROW_NUMBER() OVER(PARTITION BY ColumnValue ORDER BY (SELECT 1))
,X.ColumnValue
,Y.splitdata
FROM
(
SELECT *,
CAST('<X>'+REPLACE(F.ColumnValue,',','</X><X>')+'</X>' AS XML) AS xmlfilter FROM @t F
)X
CROSS APPLY
(
SELECT fdata.D.value('.','varchar(50)') AS splitdata
FROM X.xmlfilter.nodes('X') as fdata(D)
) Y
)X WHERE X.Rn = 3
//結果
サードバリュー
False
bannana
また、使用している SQL Server のバージョンが質問から明確ではありません。SQL SERVER 2000 を使用している場合は、以下の方法を使用できます。
ステップ 1: 数表を作成する
CREATE TABLE dbo.Numbers
(
N INT NOT NULL PRIMARY KEY
);
GO
DECLARE @rows AS INT;
SET @rows = 1;
INSERT INTO dbo.Numbers VALUES(1);
WHILE(@rows <= 10000)
BEGIN
INSERT INTO dbo.Numbers SELECT N + @rows FROM dbo.Numbers;
SET @rows = @rows * 2;
END
ステップ 2: 以下のクエリを適用する
DECLARE @t TABLE(ColumnValue VARCHAR(50))
INSERT INTO @t(ColumnValue) SELECT 'josh,Reg01,False,a0-t0,22/09/2010'
INSERT INTO @t(ColumnValue) SELECT 'mango,apple,bannana,grapes'
INSERT INTO @t(ColumnValue) SELECT 'stackoverflow'
--Declare a table variable to put the identity column and store the indermediate results
DECLARE @tempT TABLE(Id INT IDENTITY,ColumnValue VARCHAR(50),SplitData VARCHAR(50))
-- Insert the records into the table variable
INSERT INTO @tempT
SELECT
ColumnValue
,SUBSTRING(ColumnValue, Numbers.N,CHARINDEX(',', ColumnValue + ',', Numbers.N) - Numbers.N) AS splitdata
FROM @t
JOIN Numbers ON Numbers.N <= DATALENGTH(ColumnValue) + 1
AND SUBSTRING(',' + ColumnValue, Numbers.N, 1) = ','
--Project the filtered records
SELECT ThirdValue = X.splitdata
FROM
--The co-related subquery does the ROW_NUMBER() OVER(PARTITION BY ColumnValue)
(SELECT
Rn = (SELECT COUNT(*)
FROM @tempT t2
WHERE t2.ColumnValue=t1.ColumnValue
AND t2.Id<=t1.Id)
,t1.ColumnValue
,t1.splitdata
FROM @tempT t1)X
WHERE X.Rn =3
- 結果
サードバリュー
False
bannana
また、数値テーブルに Master..spt_Values を使用できます
DECLARE @t TABLE(ColumnValue VARCHAR(50))
INSERT INTO @t(ColumnValue) SELECT 'josh,Reg01,False,a0-t0,22/09/2010'
INSERT INTO @t(ColumnValue) SELECT 'mango,apple,bannana,grapes'
INSERT INTO @t(ColumnValue) SELECT 'stackoverflow'
--Declare a table variable to put the identity column and store the indermediate results
DECLARE @tempT TABLE(Id INT IDENTITY,ColumnValue VARCHAR(50),SplitData VARCHAR(50))
-- Insert the records into the table variable
INSERT INTO @tempT
SELECT
ColumnValue
,SUBSTRING(ColumnValue, Number ,CHARINDEX(',', ColumnValue + ',', Number ) - Number) AS splitdata
FROM @t
JOIN master..spt_values ON Number <= DATALENGTH(ColumnValue) + 1 AND type='P'
AND SUBSTRING(',' + ColumnValue, Number , 1) = ','
--Project the filtered records
SELECT ThirdValue = X.splitdata
FROM
--The co-related subquery does the ROW_NUMBER() OVER(PARTITION BY ColumnValue)
(SELECT
Rn = (SELECT COUNT(*)
FROM @tempT t2
WHERE t2.ColumnValue=t1.ColumnValue
AND t2.Id<=t1.Id)
,t1.ColumnValue
,t1.splitdata
FROM @tempT t1)X
WHERE X.Rn =3
これについては、
残念ながらSQLには存在しない String.Split(',')(2) のようなものが本当に必要ですが、これは役立つかもしれません
このソリューションと他のソリューションを使用していくつかのテストを行うことができますが、そのような状況で XML を使用すると、ほとんどの場合、最高のパフォーマンスが得られ、コーディングが少なくて済むと思います。
DECLARE @InPutCSV NVARCHAR(2000)= 'josh,Reg01,False,a0-t0,22/09/2010'
DECLARE @ValueIndexToGet INT=3
DECLARE @XML XML = CAST ('<d>' + REPLACE(@InPutCSV, ',', '</d><d>') + '</d>' AS XML);
WITH CTE(RecordNumber,Value) AS
(
SELECT ROW_NUMBER() OVER(ORDER BY T.v.value('.', 'NVARCHAR(100)') DESC) AS RecordNumber
,T.v.value('.', 'NVARCHAR(100)') AS Value
FROM @XML.nodes('/d') AS T(v)
)
SELECT Value
FROM CTE WHERE RecordNumber=@ValueIndexToGet
100000個の値を持つCSV文字列から値を取得するのに1秒かかることを確認できます。