在特定字词后返回SUBSTRING,并在第一个引号结尾

时间:2018-07-25 11:37:54

标签: sql json sql-server tsql

我正在尝试在特定单词之前和之后返回SUBSTRING数据。例如选择name之后到quote(")之后的所有内容。我需要对字符串中的每个必填字段重复此操作。

这是我需要从中提取数据的示例便笺值:

[
   {
      "code":"0123456",
      "name":"example",
      "table":"exampletable",
      "addedby":"exampleperson",
      "dateadded":1520333304750,
      "qualifier":[
         {
            "name":"Qualifier",
            "value":"examplevalue",
            "code":"123456",
            "prefix":"[?] "
         }
      ],
      "prefix":"[?] ",
      "suffix":""
   },
   {
      "code":"68566005",
      "name":"example2",
      "table":"exampletable2",
      "addedby":"exampleperson2",
      "dateadded":1519874550441,
      "qualifier":[
         {
            "name":"Qualifier",
            "value":"examplevalue2",
            "code":"415684004 ",
            "prefix":"[?] "
         }
      ],
      "prefix":"[?] ",
      "suffix":""
   }
]

这是我从中提取name的尝试:

select SUBSTRING(NoteValue, CHARINDEX('name', NoteValue), LEN(NoteValue))NoteValue 

它从注释键的“ name”部分开始,但我需要弄清楚如何在特定点结束它,最终结果是我将能够从中选择每个字段的每个值字符串。

使这一点更加复杂的部分是,可能需要从字符串中提取多个name字段。

希望我的问题有道理。谢谢。

4 个答案:

答案 0 :(得分:1)

尝试:

SELECT 
    substring( SUBSTRING(NoteValue, CHARINDEX('name', NoteValue)+4,LEN(NoteValue)),1, charindex('(").',NoteValue) )    
FROM ( 

SELECT  '
[{"code":"0123456" ,"name":"example" ,"table":"exampletable" 
,"addedby":"exampleperson" ,"dateadded":1520333304750, "qualifier":[{"name":"Qualifier" ,"value":"examplevalue" 
,"code":"123456", "prefix":"[?] "}] ,"prefix":"[?] " ,"suffix":""} ,{"code":"68566005" ,"name":"example2" ,"table":"exampletable2"
, "addedby":"exampleperson2" ,"dateadded":1519874550441, "qualifier":[{"name":"Qualifier" ,"value":"examplevalue2" ,"code":"415684004 
","prefix":"[?] "}] ,"prefix":"[?] " ,"suffix":""}]' NoteValue 
 ) s 

答案 1 :(得分:1)

我做了一些跳舞,但这是使用字符串函数的解决方案:

.custom-label-style {
  text-decoration: none;
};

答案 2 :(得分:1)

您可以使用分离器,我会使用delimitedSplit8K

解决方案:

DECLARE @string VARCHAR(8000) = 
'[
   {
      "code":"0123456",
      "name":"example",
      "table":"exampletable",
      "addedby":"exampleperson",
      "dateadded":1520333304750,
      "qualifier":[
         {
            "name":"Qualifier",
            "value":"examplevalue",
            "code":"123456",
            "prefix":"[?] "
         }
      ],
      "prefix":"[?] ",
      "suffix":""
   },
   {
      "code":"68566005",
      "name":"example2",
      "table":"exampletable2",
      "addedby":"exampleperson2",
      "dateadded":1519874550441,
      "qualifier":[
         {
            "name":"Qualifier",
            "value":"examplevalue2",
            "code":"415684004 ",
            "prefix":"[?] "
         }
      ],
      "prefix":"[?] ",
      "suffix":""
   }
]';

SELECT f.nodeName, f.nodeValue
FROM 
(
  SELECT 
    s.*, 
    nodeName  = LAG(s.item,1)  OVER (ORDER BY s.itemNumber),
    nodeValue = LEAD(s.item,1) OVER (ORDER BY s.itemNumber)
  FROM samd.delimitedSplitAB8K(@string,'"') s
) f
WHERE item = ':';

结果:

nodeName          nodeValue
----------------- ----------------------------
code              0123456
name              example
table             exampletable
addedby           exampleperson
name              Qualifier
value             examplevalue
code              123456
prefix            [?] 
prefix            [?] 
suffix            
code              68566005
name              example2
table             exampletable2
addedby           exampleperson2
name              Qualifier
value             examplevalue2
code              415684004 
prefix            [?] 
prefix            [?] 
suffix            

答案 3 :(得分:0)

如果您使用的是SQL Server 2016+版本,则openjson可以很好地解决问题

https://docs.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql?view=sql-server-2017

一个挑战是该json中的嵌套数组,这是一个示例:

    DECLARE @json NVARCHAR(MAX);

    SET @json = N'
            [
       {
          "code":"0123456",
          "name":"example",
          "table":"exampletable",
          "addedby":"exampleperson",
          "dateadded":1520333304750,
          "qualifier":[
             {
                "name":"Qualifier",
                "value":"examplevalue",
                "code":"123456",
                "prefix":"[?] "
             }
          ],
          "prefix":"[?] ",
          "suffix":""
       },
       {
          "code":"68566005",
          "name":"example2",
          "table":"exampletable2",
          "addedby":"exampleperson2",
          "dateadded":1519874550441,
          "qualifier":[
             {
                "name":"Qualifier",
                "value":"examplevalue2",
                "code":"415684004 ",
                "prefix":"[?] "
             }
          ],
          "prefix":"[?] ",
          "suffix":""
       }
    ]
            ';

    --Top level array
    SELECT [code]
         , [name]
         , [table]
         , [addedby]
         , [dateadded]
         , [prefix]
         , [suffix]
    FROM
           OPENJSON(@json, '$')
               WITH (
                        [code] NVARCHAR(200) '$.code'
                      , [name] NVARCHAR(200) '$.name'
                      , [table] NVARCHAR(200) '$.table'
                      , [addedby] NVARCHAR(200) '$.addedby'
                      , [dateadded] NVARCHAR(200) '$.dateadded'
                      , [prefix] NVARCHAR(200) '$.prefix'
                      , [suffix] NVARCHAR(200) '$.suffix'
                    );

    --Get data from the nested array qualifier
    SELECT [b].[name]
         , [b].[value]
         , [b].[code]
         , [b].[prefix]
    FROM   OPENJSON(@json, '$') [a]
    CROSS APPLY
           OPENJSON([a].[Value], '$.qualifier') --this gets you into the nested array
               WITH (
                        [name] NVARCHAR(200) '$.name'
                      , [value] NVARCHAR(200) '$.value'
                      , [code] NVARCHAR(200) '$.code'
                      , [prefix] NVARCHAR(200) '$.prefix'
                    ) [b];

    --if all you want is the name column from both the top level array AND the nested array, you could use a union all:
    SELECT [name]
    FROM
           OPENJSON(@json, '$')
               WITH (
                        [name] NVARCHAR(200) '$.name'
                    )
    UNION ALL
    SELECT [b].[name]
    FROM   OPENJSON(@json, '$') [a]
    CROSS APPLY
           OPENJSON([a].[Value], '$.qualifier') --this gets you into the nested array
               WITH (
                        [name] NVARCHAR(200) '$.name'
                    ) [b];