Sql-Server-2008
SQL Server 2008 - 使用其他表中的數據替換視圖行中的 csv 子字元串
使用 SQL Server 2008,有沒有辦法在視圖中執行 SELECT 查詢,將包含逗號分隔值的行替換為來自另一個表的相應文本值?STRING_SPLIT 和 STRING_AGG 在 2008 版本中不可用。
編輯: 添加了創建和插入腳本
CREATE TABLE Data( Id int, Value1 varchar(50) NULL, Value2 int NULL, Value3 datetime ) GO CREATE TABLE CodeValue( Id int, Code varchar(50) NULL ) GO INSERT [dbo].[Data] ([Id], [Value1], [Value2], [Value3]) VALUES (1, N'0;1;2', 43, CAST(N'2020-07-09T00:00:00.000' AS DateTime)) GO INSERT [dbo].[Data] ([Id], [Value1], [Value2], [Value3]) VALUES (2, N'0;2;3', 652, CAST(N'2020-07-03T00:00:00.000' AS DateTime)) GO INSERT [dbo].[Data] ([Id], [Value1], [Value2], [Value3]) VALUES (3, N'2', 1234, CAST(N'2020-07-02T00:00:00.000' AS DateTime)) GO INSERT [dbo].[CodeValue] ([Id], [Code]) VALUES (0, N'Apple') GO INSERT [dbo].[CodeValue] ([Id], [Code]) VALUES (1, N'Orange') GO INSERT [dbo].[CodeValue] ([Id], [Code]) VALUES (2, N'Banana') GO INSERT [dbo].[CodeValue] ([Id], [Code]) VALUES (3, N'Dogmeat') GO
考慮我的視圖包含來自兩個表的數據;Data 和 CodeValue,看起來像這樣:
Data Id | Value | Value2 | Value 3 ============================== 1| 0;1;2| some other data 2| 0;2;3| 3| 2 | CodeValue Id | Code ============= 0| Apple 1| Orange 2| Banana 3| Dogmeat
因此,在我看來,SELECT 查詢的實際輸出將是:
View Id | Value ============ 1| Apple, Orange, Banana 2| Apple, Banana, Dogmeat 3| Banana
我已經搞砸了儲存過程和函式,但無法理解這些以及如何實際實現它。
編輯 2: 使用以下模板嘗試使用 STUFF():
WITH CTE_TableName AS ( SELECT FieldA, FieldB FROM TableName) SELECT t0.FieldA , STUFF(( SELECT ',' + t1.FieldB FROM CTE_TableName t1 WHERE t1.FieldA = t0.FieldA ORDER BY t1.FieldB FOR XML PATH('')), 1, LEN(','), '') AS FieldBs FROM CTE_TableName t0 GROUP BY t0.FieldA ORDER BY FieldA;
但是,我似乎無法使用自製的 split_string 函式在拆分值上加入 codeValues:
CREATE FUNCTION dbo.tvf_SplitString (@stringToSplit VARCHAR(100)) RETURNS @returnList TABLE(Id VARCHAR(5)) AS BEGIN DECLARE @splitValue VARCHAR(5) DECLARE @post INT WHILE CHARINDEX(';', @stringToSplit) > 0 BEGIN SELECT @pos = CHARINDEX(';', @stringToSplit) SELECT @splitValue = SUBSTRING(@stringToSplit, 1, @pos-1) INSERT INTO @returnList SELECT @splitValue SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit -@pos) END INSERT INTO @returnList SELECT @stringToSplit RETURN END
作為一個笑話(但它仍然有效):
WITH cte1 AS ( SELECT id, ';'+value1+';' value1, value2, value3 FROM data ), cte2 AS ( SELECT id, ';'+CAST(id AS VARCHAR)+';' sid, ';'+code+';' code FROM codevalue ), cte3 AS ( SELECT cte1.id, REPLACE(cte1.value1, cte2.sid, cte2.code) value1, cte1.value2, cte1.value3, cte2.id cid FROM cte1 JOIN cte2 ON cte2.id = 0 UNION ALL SELECT cte3.id, REPLACE(cte3.value1, cte2.sid, cte2.code) value1, cte3.value2, cte3.value3, cte2.id FROM cte3 JOIN cte2 ON cte2.id = cte3.cid + 1 ) SELECT id, SUBSTRING(value1, 2, LEN(value1) - 2) value1, value2, value3 FROM cte3 WHERE cid = ( SELECT MAX(id) FROM codevalue ) ORDER BY id
需求
CodeValue.id
沒有差距。如果沒有,則添加 ROW_NUMBER() 列cte2
並將其用於下一個程式碼值行選擇(不要忘記將靜態部分的起始值從 0 更改為 1)。