在SQL中查询没有节点的JSON数据

时间:2018-11-27 14:49:44

标签: sql json sql-server tsql sql-server-2014

我在SQL Server中有一列包含JSON数据的列,其值如下:

+----+-------------------------------------------------------------+
| ID |                           Values                            |
+----+-------------------------------------------------------------+
|  1 | [{"Name":"Test1","Type":null}]                              |
|  2 | [{"Name":"Test2","Type":null}]                              |
|  3 | [{"Name":"Test3","Type":null},{"Name":"Test4","Type":null}] |
|  4 | [{"Name":"Test5","Type":null},{"Name":"Test6","Type":null}] |
+----+-------------------------------------------------------------+

我想用SQL查询上表,并希望结果为:

+----+---------+
| ID |  Values |
+----+---------+
|  1 | Test1   |
|  2 | Test2   |
|  3 | Test3   |
|  3 | Test4   |
|  4 | Test5   |
|  4 | Test6   |
+----+---------+

2 个答案:

答案 0 :(得分:0)

自2014年起,如果您愿意使用表值函数,请考虑以下内容。

我厌倦了提取字符串,所以我修改了一个解析函数以接受两个非相似的定界符。在这种情况下,'"Name":"''"'

示例

Select A.ID 
      ,[Values]=B.RetVal
 From  YourTable A
 Cross Apply [dbo].[tvf-Str-Extract]([Values],'"Name":"','"') B

返回

ID  Values
1   Test1
2   Test2
3   Test3
3   Test4
4   Test5
4   Test6

感兴趣的功能

CREATE FUNCTION [dbo].[tvf-Str-Extract] (@String varchar(max),@Delimiter1 varchar(100),@Delimiter2 varchar(100))
Returns Table 
As
Return (  

with   cte1(N)   As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
       cte2(N)   As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 N1,cte1 N2,cte1 N3,cte1 N4,cte1 N5,cte1 N6) A ),
       cte3(N)   As (Select 1 Union All Select t.N+DataLength(@Delimiter1) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter1)) = @Delimiter1),
       cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter1,@String,s.N),0)-S.N,8000) From cte3 S)

Select RetSeq = Row_Number() over (Order By N)
      ,RetPos = N
      ,RetVal = left(RetVal,charindex(@Delimiter2,RetVal)-1) 
 From  (
        Select *,RetVal = Substring(@String, N, L) 
         From  cte4
       ) A
 Where charindex(@Delimiter2,RetVal)>1

)

答案 1 :(得分:0)

如果您不能使用SQL Server 2016或CLR函数,并且您的json非常简单,则可以将其转换为xml并使用SQL Server xml support

CREATE function [RPT].[MonthlyRollupDates_Delimited]()
RETURNS @table TABLE (Value varchar(max))
AS
BEGIN

Declare @Count int , @Date date = getdate(),@Month int
SET @Month = MONTH(@Date)
SET  @Count = @Month +12


Select 
top (@Count) 
CalendarDate,   BusinessDay, Label
from  MonthlyRollupDates
order by Calendardate desc

return
end
GO