Пропустить создание JSON_OBJECT, если данных нет - PullRequest
0 голосов
/ 05 августа 2020

Я работаю над созданием одного JSON_OBJECT, который имеет несколько слоев, которые не должны создавать JSON_OBJECT, если нет совпадающих данных. В этом примере я показываю, как я создаю его, пропуская уровень, если нет данных, но я надеюсь, что есть лучший и простой способ сделать это, поскольку я не могу заставить этот способ работать с текущей проблемой. Конечное место для этого JSON не может обрабатывать пустые JSON_OBJECTS, поэтому они хотели бы, чтобы они были исключены из файла.

Это некоторые образцы данных: Условие: Condition

Action: Действие

Как видите, для одного из условий нет подходящего действия. Вот как я сейчас создаю JSON, который не удаляет лишний JSON_OBJECT по мере необходимости, но показывает, как я создаю один уровень, если это необходимо для иностранного языка.

     With      
                                           
-- Create All of the (actions)         
 fAction1 as (                                 
  Select CONCCD, CONDID,     
      Case when PADSecLangCode = '' then   
    json_object(                                 
     'actionID'            : trim(ACTID),      
     'actionDescription' : trim(DESC),    
    'active'                 : ACTIVE)
  Else                                                    
  json_object(              
       'actionID'          : trim(ACTID),      
     'actionDescription' : trim(DESC),    
     'active'                : ACTIVE,     
      'recordTexts' : json_object( 
       'recordText' : json_array( json_object( 
         'languageID'        : trim(PADSecLangCode), 
         'actionDescription' : trim(DESCF),    
         'active'                : ACTIVE )))     )     
  End          
               as sAction1                               
   From PADWCA) 


-- Create All of the Conditions (conditions/actions)         
 , fCondition1 as (                                 
  Select CONCCD,   
   Case when PADSecLangCode = '' then   
    json_object(                                 
     'conditionID'            : trim(CONDID),      
     'conditionDescription' : trim(DESC),    
    'active'                     : ACTIVE,
        'actions' : json_object(
          'action' : json_array( 
         (Select sAction1  
          From fAction1 a
          Where a.CONCCD = c.CONCCD and a.CONDID = c.CONDID
                            ) format json    
                              ) format json  
                                ) format json )       
  Else                                                    
  json_object(    
     'conditionID'            : trim(CONDID),      
     'conditionDescription' : trim(DESC),    
    'active'                     : ACTIVE,
    'recordTexts' : json_object( 
     'recordText' : json_array( json_object( 
       'languageID'             : trim(PADSecLangCode), 
       'conditionDescription' : trim(DESCF),    
          'active'                 : ACTIVE ))),     
        'actions' : json_object(
          'action' : json_array( 
         (Select sAction1  
          From fAction1 a
          Where a.CONCCD = c.CONCCD and a.CONDID = c.CONDID
                        ) format json    
                          ) format json  
                            ) format json   )
End
               as sCondition1  
   From PADWCC  c)  

- Create оболочка для Condion / action, fCondition2 as (выберите json_object ('condition': json_arrayagg (sCondition1 format json)) as sCondition2 из fCondition1)

- Создайте окончательный результат Выберите json_object ('условия': формат sCondition2 json) From fCondition2;

Вот результаты, которые я сейчас получаю:

{
"conditions": {
    "condition": [
        {
            "conditionID": "038-00068-C32",
            "conditionDescription": "Exclusion service repairs were made to the following areas:",
            "active": "false",
            "recordTexts": {
                "recordText": [
                    {
                        "languageID": "FR",
                        "conditionDescription": "Service de réparations d'exclusion ont été faites aux domaines suivants:",
                        "active": "false"
                    }
                ]
            },
            "actions": {
                "action": []
            }
        },
        {
            "conditionID": "020-00050-C26",
            "conditionDescription": "The area was very clean and in excellent condition!",
            "active": "false",
            "recordTexts": {
                "recordText": [
                    {
                        "languageID": "FR",
                        "conditionDescription": "La zone était très propre et en excellent état!",
                        "active": "false"
                    }
                ]
            },
            "actions": {
                "action": [
                    {
                        "actionID": "001-051-C26",
                        "actionDescription": "Please thank everyone who cleaned the area!",
                        "active": "false",
                        "recordTexts": {
                            "recordText": [
                                {
                                    "languageID": "FR",
                                    "actionDescription": "'il vous plaît remercier tous ceux qui nettoyé la zone!",
                                    "active": "false"
                                }
                            ]
                        }
                    }
                ]
            }
        }
    ]
}

}

Это результаты, которые я пытаюсь получить:

{
"conditions": {
    "condition": [
        {
            "conditionID": "038-00068-C32",
            "conditionDescription": "Exclusion service repairs were made to the following areas:",
            "active": "false",
            "recordTexts": {
                "recordText": [
                    {
                        "languageID": "FR",
                        "conditionDescription": "Service de réparations d'exclusion ont été faites aux domaines suivants:",
                        "active": "false"
                    }
                ]
            },
        },
        {
            "conditionID": "020-00050-C26",
            "conditionDescription": "The area was very clean and in excellent condition!",
            "active": "false",
            "recordTexts": {
                "recordText": [
                    {
                        "languageID": "FR",
                        "conditionDescription": "La zone était très propre et en excellent état!",
                        "active": "false"
                    }
                ]
            },
            "actions": {
                "action": [
                    {
                        "actionID": "001-051-C26",
                        "actionDescription": "Please thank everyone who cleaned the area!",
                        "active": "false",
                        "recordTexts": {
                            "recordText": [
                                {
                                    "languageID": "FR",
                                    "actionDescription": "'il vous plaît remercier tous ceux qui nettoyé la zone!",
                                    "active": "false"
                                }
                            ]
                        }
                    }
                ]
            }
        }
    ]
}

}

1 Ответ

0 голосов
/ 07 августа 2020

Edit: Я обновил ответ в соответствии с вашими требованиями. Это вернуло меня к вашему исходному вопросу: я использовал nullif(xxx, json_object())

, поэтому

'actions' : actionsArray format json

теперь

'actions' : nullif(json_object( /* null if value equals empty object */
                    'action' : actionsArray format json
                    absent on null
                    ), json_object()) format json

Что касается вашего второго комментария, я использовал значения, потому что он возвращает '{}', когда нет данных, но вы можете использовать select, чтобы убедиться, что вы можете использовать

values ... into :pgmvar
-- or 
select ... into :pgmvar from ...

Извините, но ваш код не очень легко читать. Переписал так, как кажется. Структура результата немного изменена, потому что я не понимаю, почему массив recordText внутри объекта recordTexts, то же самое для действия / действий:

with
-- Test data, conditions
PADWCC (CONCCD, CONDID, DESC, DESCF, ACTIVE) as (
    values
    (1, '038-00068-C32','Exclusion service repairs were made to the following areas:', 'Service de réparations d''exclusion ont été faites aux domaines suivants:', 'false'),
    (1, '020-00050-C26','The area was very clean and in excellent condition!', 'La zone était très propre et en excellent état!', 'false')
),
-- Test data, actions
PADWCA (CONCCD, CONDID, ACTID, DESC, DESCF, ACTIVE) as (
    values
    (1 ,'020-00050-C26', '001-051-C26','Please thank everyone who cleaned the area!', 'S''il vous plaît remercier tous ceux qui nettoyé la zone!', 'false')
    --,(1 ,'020-00050-C26', 'otheraction','otheraction', 'autre action', 'false')
),
-- Step 1: create an array of translations for each action (with only one translation inside)
actionsTranslations as (
    select
        CONCCD,
        CONDID,
        ACTID,
        json_arrayagg(
            json_object(
                'languageID' : languageID,
                'actionDescription' : actionDescription,
                'active' : active
                )
            ) 
        as recordTexts
    from
        PADWCA
        cross join lateral ( -- Construct a list of text(s) from PADWCA.DESCF
            values
            ('FR', DESCF)
        ) as texts(languageID, actionDescription)
    where languageID = PADSecLangCode
    group by CONCCD, CONDID, ACTID
),
-- Step 2: Create an object for each action
actionObjects as (
    select
        CONCCD,
        CONDID,
        ACTID,
        json_object(
                'actionID' : trim(PADWCA.ACTID),
                'actionDescription' : trim(DESC),
                'active' : active,
                'recordTexts' : nullif(json_object(
                    'recordText' : recordTexts format json absent on null
                    ), json_object()) format json
                absent on null -- no recordTexts key if null
            ) actionObject
    from
        PADWCA
        left join actionsTranslations using(conccd, condid, actid)
),
-- Step 3: Create an array of actions for each condition
actions as (
    select CONCCD, CONDID, JSON_ARRAYAGG(actionObject format json) as actionsArray from actionObjects group by CONCCD, CONDID
),
-- Step 4: create an array of translations for each condition (with only one translation inside)
conditionsTranslations as (
    select
        CONCCD,
        CONDID,
        json_arrayagg(
            json_object(
                'languageID' : languageID,
                'conditionDescription' : conditionDescription,
                'active' : active
                )
            ) 
        as recordTexts
    from
        PADWCC
        cross join lateral (
            values
            ('FR', DESCF)
        ) as texts(languageID, conditionDescription)
    where languageID = PADSecLangCode
    group by CONCCD, CONDID
),
-- Step 5: Create an object for each condition
conditionObjects as (
    select
        ca.CONCCD,
        ca.CONDID,
        json_object(
                'conditionID' : trim(ca.CONDID),
                'conditionDescription' : trim(DESC),
                'active' : active,
                'recordTexts' : nullif(json_object(
                    'recordText' : recordTexts format json absent on null
                    ), json_object()) format json,
                'actions' : nullif(json_object(
                    'action' : actionsArray format json
                    absent on null
                    ), json_object()) format json
                absent on null -- absent on null applies to every key of the object so recordTexts AND actions
            ) conditionObject
    from
        PADWCC ca
        left join conditionsTranslations ct on (ct.conccd, ct.condid) = (ca.conccd, ca.condid)
        left join actions ac on (ac.conccd, ac.condid) = (ca.conccd, ca.condid)
),
-- Step 6: Create an array of conditions for each CONCCD
conditions as (
    select CONCCD, JSON_ARRAYAGG(conditionObject format json) as array from conditionObjects group by CONCCD
)
-- Wrap output in an object
values json_object('conditions' : nullif(json_object('condition' : (select conditions.array from conditions where conccd = 1) format json absent on null), json_object()) format json absent on null);
--or
--select json_object('conditions' : nullif(json_object('condition' : conditions.array format json absent on null), json_object()) format json absent on null) from conditions where conccd = 2;

дает

{
    "conditions": {
        "condition": [
            {
                "conditionID": "038-00068-C32",
                "conditionDescription": "Exclusion service repairs were made to the following areas:",
                "active": "false",
                "recordTexts": {
                    "recordText": [
                        {
                            "languageID": "FR",
                            "conditionDescription": "Service de réparations d'exclusion ont été faites aux domaines suivants:",
                            "active": "false"
                        }
                    ]
                }
            },
            {
                "conditionID": "020-00050-C26",
                "conditionDescription": "The area was very clean and in excellent condition!",
                "active": "false",
                "recordTexts": {
                    "recordText": [
                        {
                            "languageID": "FR",
                            "conditionDescription": "La zone était très propre et en excellent état!",
                            "active": "false"
                        }
                    ]
                },
                "actions": {
                    "action": [
                        {
                            "actionID": "001-051-C26",
                            "actionDescription": "Please thank everyone who cleaned the area!",
                            "active": "false",
                            "recordTexts": {
                                "recordText": [
                                    {
                                        "languageID": "FR",
                                        "actionDescription": "S'il vous plaît remercier tous ceux qui nettoyé la zone!",
                                        "active": "false"
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        ]
    }
}
...