2016-03-23 11 views
1

Ich habe eine Spalte in jsonb Speichern einer Karte, wie {'a':1,'b':2,'c':3}, wo die Anzahl der Schlüssel in jeder Zeile unterschiedlich ist.Wie zählt man die Anzahl/Anzahl der Schlüssel von JSON in postgresql?

ich es zählen möchten - jsonb_object_keys die Schlüssel abrufen kann, aber es ist in setof

Gibt es so etwas?

(select count(jsonb_object_keys(obj) from XXX) 

(dies wird nicht als ERROR: set-valued function called in context that cannot accept a set arbeiten)

Postgres JSON Functions and Operators Document

json_object_keys(json) 
jsonb_object_keys(jsonb) 

setof text Returns set of keys in the outermost JSON object. 
json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}') 

json_object_keys 
------------------ 
f1 
f2 

Crosstab ist nicht möglich, da die Anzahl der Schlüssel groß sein könnte.

Antwort

3

Sie könnten Schlüssel zum Array umwandeln und verwenden array_length dies zu erhalten:

select array_length(array_agg(A.key), 1) from (
    select json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}') as key 
) A; 

Wenn Sie dies für die gesamte Tabelle müssen bekommen, können Sie nach dem Primärschlüssel gerade Gruppe.

1

Alternativ können Sie einfach die obere Grenze der Schlüssel zurück, wenn als Array aufgelistet:

SELECT 
    ARRAY_UPPER(-- Grab the upper bounds of the array 
     ARRAY(-- Convert rows into an array. 
      SELECT JSONB_OBJECT_KEYS(obj) 
     ), 
     1 -- The array's dimension we're interested in retrieving the count for 
    ) AS count 
FROM 
    xxx 

'{"a": 1, "b": 2, "c": 3}'::jsonb als obj Unter Verwendung Zählung in einem Wert von drei führen würde (3).

Pasteable Beispiel:

SELECT 
    ARRAY_UPPER(-- Grab the upper bounds of the array 
     ARRAY(-- Convert rows into an array. 
      SELECT JSONB_OBJECT_KEYS('{"a": 1, "b": 2, "c": 3}'::jsonb) 
     ), 
     1 -- The array's dimension we're interested in retrieving the count for 
    ) AS count 
2

Während ein Unterauswahl verwendet werden müssen, um die JSON Schlüssel zu Zeilen, die folgende gezwickt Abfrage das temporäre Array bauen könnte schneller laufen durch Überspringen gesetzt zu konvertieren:

SELECT count(*) FROM 
    (SELECT jsonb_object_keys('{"a": 1, "b": 2, "c": 3}'::jsonb)) v; 

und es ist ein bisschen kürzer;)

Um es eine Funktion zu machen:

CREATE OR REPLACE FUNCTION public.count_jsonb_keys(j jsonb) 
    RETURNS bigint 
    LANGUAGE sql 
AS $function$ 
SELECT count(*) from (SELECT jsonb_object_keys(j)) v; 
$function$ 
1

Kürzeste:

SELECT count(*) FROM jsonb_object_keys('{"a": 1, "b": 2, "c": 3}'::jsonb); 

Returns 3

Wenn Sie alle json Anzahl von Schlüsseln aus einer Tabelle wollen, gibt es:

SELECT (SELECT COUNT(*) FROM json_object_keys(myJsonField)) nbr_keys FROM myTable; 
Verwandte Themen