我有一个名为QueueItems的数据库表,其中包含以下字段:
SpecificData包含JSON数据,因此我们使用了互联网上众所周知的parseJSON SQL函数。
下面是JSON的一个例子:
{"DynamicProperties":{"IdentificationIndex":"CK","PaymentMethod":"C","Variants1":"010 ZERO BAL,716 ZERO BAL,717 ZERO BAL","Variants2":"CHECK_010,CHECK_716,CHECK_717","CustomerCode":"NO","FreeSelectionField":"NO","FreeSelectionValue":"NO","Variants1Line":"RFFOAVIS","Variants2Line":"ZRFFOUS_C","VendorFrom":"1","VendorTo":"999999999","DueDateCheck":"Yes","PaymentMethodSel":"Yes","PaymentMethodSelOnFail":"No","LineItemsOfPayDocs":"Yes","StartImmediately":"Yes","CreatePaymentMedium":"No","ExportFormat":"HTML Format","ExcludeValues":"Yes"}}
当我运行SQL函数parseJSON时,它以这种格式返回数据:
现在,我想写的查询是:
SELECT QueueItemID,QueueItemStatus,StartProcessing,EndProcessing,[THEN追加parseJSON中的每一列,但这需要先转置]
到目前为止,我已设法使用以下方法将JSON转换为具有单行的列:
DECLARE
@Cols AS VARCHAR(MAX) = ''
,@Query AS NVARCHAR(MAX) = ''
,@ParamDef AS NVARCHAR(MAX)
,@Json AS VARCHAR(MAX) = '{"DynamicProperties":{"IdentificationIndex":"CK","PaymentMethod":"C","Variants1":"010 ZERO BAL,716 ZERO BAL,717 ZERO BAL","Variants2":"CHECK_010,CHECK_716,CHECK_717","CustomerCode":"NO","FreeSelectionField":"NO","FreeSelectionValue":"NO","Variants1Line":"RFFOAVIS","Variants2Line":"ZRFFOUS_C","VendorFrom":"1","VendorTo":"999999999","DueDateCheck":"Yes","PaymentMethodSel":"Yes","PaymentMethodSelOnFail":"No","LineItemsOfPayDocs":"Yes","StartImmediately":"Yes","CreatePaymentMedium":"No","ExportFormat":"HTML Format","ExcludeValues":"Yes"}}'
SELECT
@Cols += ',' + Name
FROM
parseJson(@Json)
WHERE
Name NOT IN ('DynamicProperties', '-')
SET @Cols = SUBSTRING(@Cols,2,LEN(@Cols))
SET @Query = N'SELECT *
FROM
(
SELECT [StringValue], [Name]
FROM parseJson(''' + @Json + ''')
) [d]
PIVOT
(
MAX([StringValue])
FOR [Name] IN (' + @Cols + ')
) [piv]'
EXECUTE (@Query)
正如您所看到的,JSON可能包含任何数据,因此我将列名称动态插入到PIVOT语句FOR IN中。
现在将此数据作为附加列加入到我的主查询中 SELECT QueueItemId .. FROM QueueItems 我原本打算将此代码放在UDF中并将其作为主查询/存储的一部分进行调用程序,但我有两个问题:
1)sp_executesql或EXEC语句 - UDF中不允许使用 2)要从UDF返回一个表,我需要定义字段......这些字段是动态的......我可以通过将XML传回我的存储过程来实现这一点,但我仍然有第一个问题。
所以问题是: 1)有没有更好的方法或写这个然后使用UDF? 2)有没有其他方法或转换parseJSON的输出? 3)是否有其他方式使用PIVOT但不必指定列?
非常感谢任何帮助。
编辑对AL ALI的响应 我知道语法错误而且它不起作用,但查询看起来像这样:
DECLARE @Cols AS VARCHAR(MAX) = ''
,@Query AS NVARCHAR(MAX) = ''
SELECT
QI.QueueItemID,
QI.QueueItemStatus,
QI.StartProcessing,
QI.EndProcessing,
SD.*
FROM QueueItems AS QI
LEFT JOIN
(
SELECT
@Cols += ',' + Name
FROM
parseJson(QI.SpecificData)
WHERE
Name NOT IN ('DynamicProperties', '-')
SET @Cols = SUBSTRING(@Cols,2,LEN(@Cols))
SET @Query = N'SELECT *
FROM
(
SELECT [StringValue], [Name]
FROM parseJson(''' + QI.SpecificData + ''')
) [d]
PIVOT
(
MAX([StringValue])
FOR [Name] IN (' + @Cols + ')
) [piv]'
EXECUTE (@Query)
) AS SD
结果将是QueueItems中的列,左侧是已解析的JSON字符串中的列。
QueueItemID,StartProcessing,EndProcessing,IndentificationIndex,PaymentMethod等......