Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como retornar chaves duplicadas de um documento JSON no SQL Server


Se você estiver tentando extrair valores de um documento JSON, mas um ou mais valores no mesmo nível tiverem chaves duplicadas, poderá ter problemas se tentar extrair esses valores usando JSON_QUERY() ou JSON_VALUE() .

Ambas as funções retornarão apenas o primeiro valor que corresponde ao caminho.

Felizmente, há outra opção.

O OPENJSON() A função retornará todos os valores de qualquer chave duplicada no mesmo nível.

Exemplo


Aqui está um exemplo para demonstrar OPENJSON() retornando propriedades duplicadas no mesmo nível.
DECLARE @json NVARCHAR(4000) = N'{
    "dog" : {
            "details" : {
                "name" : "Fetch", 
                "name" : "Good Dog",
                "sex" : "male"
            }
        }
    }';
SELECT * FROM OPENJSON(@json, '$.dog.details');

Resultado:
+-------+----------+--------+
| key   | value    | type   |
|-------+----------+--------|
| name  | Fetch    | 1      |
| name  | Good Dog | 1      |
| sex   | male     | 1      |
+-------+----------+--------+

Este exemplo retorna todos os filhos de $.dog.details chave.

Neste caso, temos duas chaves com o mesmo nome no mesmo nível (o name chave).

Se quisermos retornar apenas os valores dos dois name keys, poderíamos fazer algo como o seguinte.
DECLARE @json NVARCHAR(4000) = N'{
    "dog" : {
            "details" : {
                "name" : "Fetch", 
                "name" : "Good Dog",
                "sex" : "male"
            }
        }
    }';
SELECT value FROM OPENJSON(@json, '$.dog.details')
WHERE [key] = 'name';

Resultado:
+----------+
| value    |
|----------|
| Fetch    |
| Good Dog |
+----------+

JSON_VALUE() &JSON_QUERY()


Como mencionado, ambos JSON_VALUE() e JSON_QUERY() retorne apenas o primeiro valor que corresponde ao caminho.

Portanto, se tentarmos usá-los no documento JSON acima, obteremos os seguintes resultados.

JSON_VALUE()


JSON_VALUE() retorna um valor escalar de uma string JSON, portanto, retornará o seguinte resultado.
DECLARE @json NVARCHAR(4000) = N'{
    "dog" : {
            "details" : {
                "name" : "Fetch", 
                "name" : "Good Dog",
                "sex" : "male"
            }
        }
    }';
SELECT JSON_VALUE(@json, '$.dog.details.name') AS [JSON_VALUE];

Resultado:
+--------------+
| JSON_VALUE   |
|--------------|
| Fetch        |
+--------------+

JSON_QUERY()


JSON_QUERY() extrai um objeto ou uma matriz de uma string JSON, portanto, retornará o seguinte resultado.
DECLARE @json NVARCHAR(4000) = N'{
    "dog" : {
            "details" : {
                "name" : "Fetch", 
                "name" : "Good Dog",
                "sex" : "male"
            }
        }
    }';
SELECT JSON_QUERY(@json, '$.dog.details') AS [JSON_QUERY];

Resultado:
+--------------+
| JSON_QUERY   |
|--------------|
| {
                "name" : "Fetch", 
                "name" : "Good Dog",
                "sex" : "male"
            }              |
+--------------+

Pelo menos com JSON_QUERY() conseguimos ver as chaves duplicadas, mas não obtemos seus valores individuais como obtemos com OPENJSON() .