开发者社区> 问答> 正文

选择使用T-SQL格式化为报表格式的Json

我将JSON以以下格式存储在SQL Server数据库表中。我已经能够捏造一种获得所需值的方法,但是觉得必须有一种使用T-SQL的更好的方法。JSON以以下格式从报告中输出,其中“列”中的列名称对应于“行”-“数据”数组值。

因此,“会计月份”列对应于数据值“ 11”,“会计年度”对应于“ 2019”,依此类推。

{
  "report": "Property ETL",
  "id": 2648,
  "columns": [
    {
      "name": "Fiscal Month",
      "dataType": "int"
    },
    {
      "name": "Fiscal Year",
      "dataType": "int"
    },
    {
      "name": "Portfolio",
      "dataType": "varchar(50)"
    },
    {
      "name": "Rent",
      "dataType": "int"
    }
],
"rows": [
    {
      "rowName": "1",
      "type": "Detail",
      "data": [
        11,
        2019,
        "West Group",
        10
      ]
    },
    {
      "rowName": "2",
      "type": "Detail",
      "data": [
        11,
        2019,
        "East Group",
        10
      ]
    },
    {
      "rowName": "3",
      "type": "Detail",
      "data": [
        11,
        2019,
        "East Group",
        10
      ]
    },
    {
      "rowName": "Totals: ",
      "type": "Total",
      "data": [
        null,
        null,
        null,
        30
      ]
    }
  ]
}

为了获得“数据”数组中的数据,我目前在T-SQL中有一个两步过程,在该过程中,我创建了一个临时表,然后从其中的“ $ .Rows”插入行键/值。然后,我可以为每一行选择单独的列

CREATE TABLE #TempData 
(
    Id INT,
    JsonData VARCHAR(MAX)
)

DECLARE @json VARCHAR(MAX);
DECLARE @LineageKey INT;

SET @json = (SELECT JsonString FROM Stage.Report);
SET @LineageKey = (SELECT LineageKey FROM Stage.Report);    

INSERT INTO #TempData(Id, JsonData)
    (SELECT [key], value FROM OPENJSON(@json, '$.rows'))

MERGE [dbo].[DestinationTable] TARGET
USING 
(
    SELECT 
        JSON_VALUE(JsonData, '$.data[0]') AS FiscalMonth,
        JSON_VALUE(JsonData, '$.data[1]') AS FiscalYear,
        JSON_VALUE(JsonData, '$.data[2]') AS Portfolio,
        JSON_VALUE(JsonData, '$.data[3]') AS Rent
     FROM #TempData
     WHERE JSON_VALUE(JsonData, '$.data[0]') is not null
) AS SOURCE     
... 
etc., etc.

这可行,但是我想知道是否有一种直接选择数据值的方法,而无需将其放入临时表的中间步骤。我阅读的文档和示例似乎都要求数据具有与之关联的名称才能访问它。当我尝试通过索引直接在某个位置访问数据时,我只会得到Null。

展开
收起
祖安文状元 2020-01-04 14:57:43 740 0
1 条回答
写回答
取消 提交回答
  • 是的,有可能没有临时表:

    DECLARE @json NVARCHAR(MAX) = 
    N'
    {
      "report": "Property ETL",
      "id": 2648,
      "columns": [
        {
          "name": "Fiscal Month",
          "dataType": "int"
        },
        {
          "name": "Fiscal Year",
          "dataType": "int"
        },
        {
          "name": "Portfolio",
          "dataType": "varchar(50)"
        },
        {
          "name": "Rent",
          "dataType": "int"
        }
    ],
    "rows": [
        {
          "rowName": "1",
          "type": "Detail",
          "data": [
            11,
            2019,
            "West Group",
            10
          ]
        },
        {
          "rowName": "2",
          "type": "Detail",
          "data": [
            11,
            2019,
            "East Group",
            10
          ]
        },
        {
          "rowName": "3",
          "type": "Detail",
          "data": [
            11,
            2019,
            "East Group",
            10
          ]
        },
        {
          "rowName": "Totals: ",
          "type": "Total",
          "data": [
            null,
            null,
            null,
            30
          ]
        }
      ]
    }    
    }';
    
    

    并查询:

    SELECT s.value,
      rowName = JSON_VALUE(s.value, '$.rowName'),
      [type] = JSON_VALUE(s.value, '$.type'),
      s2.[key],
      s2.value
    FROM OPENJSON(JSON_QUERY(@json, '$.rows')) s
    CROSS APPLY OPENJSON(JSON_QUERY(s.value, '$.data')) s2;
    db <> fiddle演示
    
    

    或作为每个细节的一行:

    SELECT s.value,
      rowName = JSON_VALUE(s.value, '$.rowName'),
      [type] = JSON_VALUE(s.value, '$.type'),
      JSON_VALUE(s.value, '$.data[0]') AS FiscalMonth,
      JSON_VALUE(s.value, '$.data[1]') AS FiscalYear,
      JSON_VALUE(s.value, '$.data[2]') AS Portfolio,
      JSON_VALUE(s.value, '$.data[3]') AS Rent
    FROM OPENJSON(JSON_QUERY(@json, '$.rows')) s;
    
    2020-01-04 14:59:17
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
SQL Server 2017 立即下载
GeoMesa on Spark SQL 立即下载
原生SQL on Hadoop引擎- Apache HAWQ 2.x最新技术解密malili 立即下载