我正在通过复制的Server数据库访问和创建供应商的报告。他们做了一些我一直想解决的疯狂的事情,但这件事就是我想要解决的。
它们有一个有许多标准列的表。但是这个表也有一个名为"Data“的列。该列是一个遗留的“文本”数据类型,它包含一个巨大的(数百)键/值对列表。每对由一个CRLF分隔,键和值用等号分隔。示例:
select myTable.[data] from myTable where tblKey = 123结果:
Key 1=Value 1
Key 2=Value 2
Key 3=Value 3
...
Key 500=Value 500我正在尝试确定最有效的方法将该列分解为可用的数据表。最终目标是能够以这样的方式查询表,将表键连同指定的键/值作为列/字段返回:
tblKey | [Key 1] | [Key 3] | [Key 243]
-------|---------|---------|-----------
123 Value 1 Value 3 Value 243
124 Value 1 Value 3 Value 243
125 Value 1 Value 3 Value 243有办法把那列塑造成视图吗?我无法想象一个函数会特别高效,但我确信我可以用string_split或类似的方法来解析事情。有没有人遇到过这种暴行,并找到了一个很好的方法来操纵它成为可用的数据?
编辑以添加[医]小提琴示例数据。
数据是从供应商的源复制的,因此我无法创建新的表。我可以创建视图、过程和功能。这就是我正在寻求的建议,一个体面的方式来完成。
发布于 2019-09-25 20:37:31
McNets提供了一种合理的方法,但是对每对进行拆分虽然显然是必要的,但这是一个非常耗时的过程。对于表中的每一条记录,使用500+键/值对,我不确定它是否能达到我的目的。如果受影响的表中有较少的对和少量行,这可能是一种不错的方法。
由于我正在处理数百个键/值对以及表本身中的数千条记录,所以我正在考虑实现一个用户定义的函数(如下所示),以便在需要(并且已知)特定的键/值对的报表和查询中使用它。
CREATE FUNCTION udfsv_GetFruitDataValue(
@FruitID int,
@DataId varchar(100)
)
RETURNS varchar(100)
AS BEGIN
DECLARE @DataVal varchar(100)
set @DataVal = (
select
replace(replace(split1, @DataId + '=', ''), char(13), '') as DataValue
from Fruit
left outer join (
select
FruitID,
value as split1
from Fruit
cross apply string_split(cast([data] as varchar(max)), char(10))
) line1 on line1.FruitID = Fruit.FruitID
where Fruit.FruitID = @FruitID
and split1 like @DataId + '=%'
)
RETURN @DataVal
END有了这个,我就可以执行查询来包含指定的键/值,而不是所有的键/值。
SELECT
FruitID,
Name,
Description,
udfsv_GetFruitDataValue(FruitID, 'Key 1') as [Key 1],
udfsv_GetFruitDataValue(FruitID, 'Key 4') as [Key 4]
FROM
Fruit
WHERE FruitID = 123https://dba.stackexchange.com/questions/249593
复制相似问题