col*_*s91 2 sql sql-server stored-procedures
我试图找出解析在SQL Server中存储为字符串的复杂JSON对象的最佳方法.
我的表有以下信息:
LogID | Content
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
55271413 | {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218912","CarrierScac":"XYZ","Latitude":33.595555,"Longitude":-85.854722,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271414 | {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218944","CarrierScac":"XYZ","Latitude":37.996666,"Longitude":-78.314444,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271415 | {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219079","CarrierScac":"YZB","Latitude":34.027500,"Longitude":-117.522222,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271416 | {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219020","CarrierScac":"XYZ","Latitude":37.754722,"Longitude":-121.144166,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271417 | {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218911","CarrierScac":"XYZ","Latitude":40.585833,"Longitude":-91.425000,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271418 | {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218785","CarrierScac":"XYZ","Latitude":30.747500,"Longitude":-85.270277,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271426 | {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219044","CarrierScac":"XYZ","Latitude":33.598333,"Longitude":-97.936388,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
Run Code Online (Sandbox Code Playgroud)
我正在尝试解析每个字符串并将其放在一个新列中,其中JSON属性的名称作为列名,相应的值作为行值.
例如,以下是我在下面为每行寻找的结果:
LogID | LicensePlate | FreightHaulerProviderXId | FreightProviderReferenceNumber | CarrierScac | Latitude | Longitude | StreetAddress1 | StreetAddress2 | City | State | PostalCode | Country
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
55271413 | | ABC | 5218912 | XYZ | 33.595555 | -85.854722 | | | | | |
Run Code Online (Sandbox Code Playgroud)
我尝试使用一些非常糟糕的SQL逻辑来解析它.基本上我查找整个字符串,获取子字符串,然后手动分配列名.对于可伸缩性和性能而言,这不是一个非常好的解决方案.
SELECT DISTINCT
SUBSTRING(lcon.Content, CHARINDEX('CarrierScac', lcon.Content)+14, CHARINDEX('City',lcon.Content) - CHARINDEX('CarrierScac', lcon.Content) + Len('City')-21) as 'CarrierScac',
SUBSTRING(lcon.Content, CHARINDEX('Latitude', lcon.Content)+10, CHARINDEX('Longitude',lcon.Content) - CHARINDEX('Latitude', lcon.Content) + Len('Longitude')-21) as 'Latitude',
SUBSTRING(lcon.Content, CHARINDEX('Longitude', lcon.Content)+11, CHARINDEX('PositionEventType',lcon.Content) - CHARINDEX('Longitude', lcon.Content) + Len('"PositionEventType')-31) as 'Longitude'
FROM
acg.LogContext lcon
WHERE
lcon.Content LIKE '%XYZ%'
Run Code Online (Sandbox Code Playgroud)
任何帮助都会受到赞赏,因为即使在研究了一天中更好的一半技术后,我似乎也完全被困住了.
谢谢!
借助解析函数和两个交叉应用...
Declare @YourTable table (LogID int,Content varchar(max))
Insert Into @YourTable values
(55271413,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218912","CarrierScac":"XYZ","Latitude":33.595555,"Longitude":-85.854722,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271414,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218944","CarrierScac":"XYZ","Latitude":37.996666,"Longitude":-78.314444,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271415,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219079","CarrierScac":"YZB","Latitude":34.027500,"Longitude":-117.522222,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271416,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219020","CarrierScac":"XYZ","Latitude":37.754722,"Longitude":-121.144166,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271417,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218911","CarrierScac":"XYZ","Latitude":40.585833,"Longitude":-91.425000,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271418,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218785","CarrierScac":"XYZ","Latitude":30.747500,"Longitude":-85.270277,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271426,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219044","CarrierScac":"XYZ","Latitude":33.598333,"Longitude":-97.936388,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}')
Select LogID
,LicensePlate = max(case when Item='LicensePlate' then Value else null end)
,FreightHaulerProviderXId = max(case when Item='FreightHaulerProviderXId' then Value else null end)
,FreightProviderReferenceNumber = max(case when Item='FreightProviderReferenceNumber' then Value else null end)
,CarrierScac = max(case when Item='CarrierScac' then Value else null end)
,Latitude = max(case when Item='Latitude' then Value else null end)
,Longitude = max(case when Item='Longitude' then Value else null end)
,StreetAddress1 = max(case when Item='StreetAddress1' then Value else null end)
,StreetAddress2 = max(case when Item='StreetAddress2' then Value else null end)
,City = max(case when Item='City' then Value else null end)
,State = max(case when Item='State' then Value else null end)
,PostalCode = max(case when Item='PostalCode' then Value else null end)
,Country = max(case when Item='Country' then Value else null end)
From (
Select LogID
,Item = max(case when RetSeq=1 then RetVal else null end)
,Value = max(case when RetSeq=2 then RetVal else null end)
From (
Select A.LogID
,Grp = B.RetSeq
,C.*
From @YourTable A
Cross Apply (Select RetSeq,RetVal=Replace(Replace(Replace(RetVal,'"',''),'{',''),'}','') From [dbo].[udf-Str-Parse](A.Content,',') ) B
Cross Apply (Select * From [dbo].[udf-Str-Parse](B.RetVal,':') ) C
) N Group By LogID,Grp
) F
Group By LogID
Run Code Online (Sandbox Code Playgroud)
返回
UDF如果需要的话
CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table
As
Return (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>'+ Replace(@String,@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
);
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
112 次 |
| 最近记录: |