层次化JSON的T-SQL

问题描述 投票:0回答:1

我需要从位于Azure Blob存储中的JSON中提取数组到Azure SQL DB。

"vehicleStatusResponse": {
    "vehicleStatuses": [
        {
            "vin": "ABC1234567890",
            "triggerType": {
                "triggerType": "TIMER",
                "context": "RFMS",
                "driverId": {
                    "tachoDriverIdentification": {
                        "driverIdentification": "123456789",
                        "cardIssuingMemberState": "BRA",
                        "driverAuthenticationEquipment": "CARD",
                        "cardReplacementIndex": "0",
                        "cardRenewalIndex": "1"
                    }
                }
            },
            "receivedDateTime": "2020-02-12T04:11:19.221Z",
            "hrTotalVehicleDistance": 103306960,
            "totalEngineHours": 3966.6216666666664,
            "driver1Id": {
                "tachoDriverIdentification": {
                    "driverIdentification": "BRA1234567"
                }
            },
            "engineTotalFuelUsed": 48477520,
            "accumulatedData": {
                "durationWheelbaseSpeedOverZero": 8309713,
                "distanceCruiseControlActive": 8612200,
                "durationCruiseControlActive": 366083,
                "fuelConsumptionDuringCruiseActive": 3064170,
                "durationWheelbaseSpeedZero": 5425783,
                "fuelWheelbaseSpeedZero": 3332540,
                "fuelWheelbaseSpeedOverZero": 44709670,
                "ptoActiveClass": [
                    {
                        "label": "wheelbased speed >0",
                        "seconds": 16610,
                        "meters": 29050,
                        "milliLitres": 26310
                    },
                    {
                        "label": "wheelbased speed =0",
                        "seconds": 457344,
                        "milliLitres": 363350

我用OPENJSON的T-SQL脚本。


DECLARE @json AS NVARCHAR(MAX);

SELECT @json = r.BulkColumn
    FROM OPENROWSET (BULK 'response.json', DATA_SOURCE = '34524', SINGLE_CLOB) AS r

SELECT * FROM OPENJSON (@json, '$.vehicleStatusResponse.vehicleStatuses' )
WITH (
    vin NVARCHAR(50)  '$.vin',
    triggerType NVARCHAR(50)  '$.triggerType.triggerType',
    driverIdentification NVARCHAR(50)     '$.triggerType.driverId.tachoDriverIdentification.driverIdentification',
    cardIssuingMemberState NVARCHAR(50)   '$.triggerType.driverId.tachoDriverIdentification.cardIssuingMemberState',
    receivedDateTime DATETIME    '$.receivedDateTime',
    hrTotalVehicleDistance INT '$.hrTotalVehicleDistance',
    totalEngineHours FLOAT '$.totalEngineHours',
    engineTotalFuelUsed INT  '$.engineTotalFuelUsed',
    durationWheelbaseSpeedOverZero INT '$.accumulatedData.durationWheelbaseSpeedOverZero',
    distanceCruiseControlActive INT '$.accumulatedData.distanceCruiseControlActive',
    durationCruiseControlActive INT '$.accumulatedData.durationCruiseControlActive',
    fuelWheelbaseSpeedZero INT '$.accumulatedData.fuelWheelbaseSpeedZero',
    fuelWheelbaseSpeedOverZero INT '$.accumulatedData.fuelWheelbaseSpeedOverZero',
      ptoActiveClass NVARCHAR(MAX) '$.accumulatedData.ptoActiveClass' AS JSON

    ) as FIRST

CROSS APPLY OPENJSON (ptoActiveClass) 
WITH (
    label NVARCHAR(50),
    seconds INT,
    meters INT
);

我面临的问题是,当PTOActiveClass数组 "label "在表中产生双倍的其他行时。我需要为每个标签获得不同的列(轴距速度> 0,轴距=0)。

我应该怎么改?我需要解决这个问题,为我的毕业论文工作做进一步的数据分析。

PTOActiveClass label

json sql-server azure tsql azure-sql-database
1个回答
1
投票

一种选择是使用条件聚合,如

SELECT vin, triggerType, driverIdentification, cardIssuingMemberState, receivedDateTime, 
       hrTotalVehicleDistance, totalEngineHours, engineTotalFuelUsed, durationWheelbaseSpeedOverZero, 
       distanceCruiseControlActive, durationCruiseControlActive, fuelWheelbaseSpeedZero, fuelWheelbaseSpeedOverZero, 
       MAX(CASE WHEN l.label = 'wheelbased speed =0' THEN seconds END) AS [seconds for speed =0],
       MAX(CASE WHEN l.label = 'wheelbased speed >0' THEN seconds END) AS [seconds for speed >0],
       MAX(CASE WHEN l.label = 'wheelbased speed =0' THEN meters  END) AS [meters for speed =0],
       MAX(CASE WHEN l.label = 'wheelbased speed >0' THEN meters  END) AS [meters for speed >0]
  FROM OPENJSON (@json, '$.vehicleStatusResponse.vehicleStatuses' )
  WITH (
        vin                            NVARCHAR(50)  '$.vin',
        triggerType                    NVARCHAR(50)  '$.triggerType.triggerType',
        driverIdentification           NVARCHAR(50)  '$.triggerType.driverId.tachoDriverIdentification.driverIdentification',
        cardIssuingMemberState         NVARCHAR(50)  '$.triggerType.driverId.tachoDriverIdentification.cardIssuingMemberState',
        receivedDateTime               DATETIME      '$.receivedDateTime',
        hrTotalVehicleDistance         INT           '$.hrTotalVehicleDistance',
        totalEngineHours               FLOAT         '$.totalEngineHours',
        engineTotalFuelUsed            INT           '$.engineTotalFuelUsed',
        durationWheelbaseSpeedOverZero INT           '$.accumulatedData.durationWheelbaseSpeedOverZero',
        distanceCruiseControlActive    INT           '$.accumulatedData.distanceCruiseControlActive',
        durationCruiseControlActive    INT           '$.accumulatedData.durationCruiseControlActive',
        fuelWheelbaseSpeedZero         INT           '$.accumulatedData.fuelWheelbaseSpeedZero',
        fuelWheelbaseSpeedOverZero     INT           '$.accumulatedData.fuelWheelbaseSpeedOverZero',
        ptoActiveClass                 NVARCHAR(MAX) '$.accumulatedData.ptoActiveClass' AS JSON
    ) 
 CROSS APPLY OPENJSON (ptoActiveClass) 
 WITH (
       label   NVARCHAR(50),
       seconds INT,
       meters  INT
 ) AS l
GROUP BY vin, triggerType, driverIdentification, cardIssuingMemberState, receivedDateTime, 
         hrTotalVehicleDistance, totalEngineHours, engineTotalFuelUsed, durationWheelbaseSpeedOverZero, 
         distanceCruiseControlActive, durationCruiseControlActive, fuelWheelbaseSpeedZero, fuelWheelbaseSpeedOverZero;

价值 @json 变量前应加一个大括号。{ 并在后面加上大括号和方括号。} ] } } ] } }.

ISJSON() 函数可以用来检查 SELECT ISJSON( @json ) 查询返回1(有效)或0(无效)。

演示

© www.soinside.com 2019 - 2024. All rights reserved.