2017-10-17 26 views
1

J'essaie de comprendre pourquoi cela fonctionne:Nest une instruction select dans array_to_json (de array_agg (row_to_json())) dans PostgreSQL

select 
    array_to_json(array_agg(row_to_json(positions_table))) 
from (
    select 
     sum(start_month), 
     function_id, 
     profile_id 
    from positions as subquery 
    group by function_id, profile_id 
) as positions_table 

Mais cela ne:

select 
    profiles.id, 
    (array_to_json(array_agg(row_to_json(
     select 
      sum(start_month), 
      function_id, 
      profile_id 
     from positions as subquery 
     group by function_id, profile_id 
    )))) 
from profiles 

Il semble comme je ne suis pas autorisé à mettre l'instruction select... à l'intérieur array_to_json(array_agg(row_to_json())) et qu'il a besoin de référencer une table à la place.

Mais je me méfie peut-être de manquer quelque chose.

L'erreur est syntax error near select.

+0

Pour votre information: au lieu de faire 3 conversions de données (JSON, tableau, JSON) vous devez utiliser 'jsonb_agg()' la place pour votre résultat wishful [voir plus] (https://www.postgresql.org/docs/9.6/ static/functions-aggregate.html). En outre, 'row_to_json' attend' record' en entrée, la sous-requête n'est pas un enregistrement, il est défini comme un ensemble d'enregistrements, donc vous ne pouvez pas vous attendre à ce que function ait pour but de convertir 1 ligne en json pour convertir N lignes. –

Répondre

1

Vous pourriez corriger votre erreur de syntaxe en enveloppant votre sous-sélection entre parenthèses, mais alors vous verriez votre deuxième erreur; postgres déclareraient:

sous-requête doit retourner

une seule colonne

Si vous avez validé que erreur vous verriez:

colonne "profiles.id" doit apparaître dans la La clause GROUP BY ou être utilisée dans une fonction d'agrégat

... qui se rapproche de La véritable cause de votre problème. Ajout GROUP BY id va se postgres à signaler la cause racine:

plus d'une ligne retournée par une sous-requête utilisé comme une expression

La fonction row_to_json attend une seule ligne.

Pour agréger vos résumés json par profil, vous devez effectuer une jointure.

SELECT 
    pr.id, 
    array_to_json(array_agg(row_to_json(positions_table.*))) 
FROM profiles pr JOIN (
    SELECT sum(start_month), function_id, profile_id 
    FROM positions 
    GROUP BY function_id, profile_id 
) positions_table ON positions_table.profile_id = pr.id 
GROUP BY pr.id 

(Vous pouvez laisser tomber le .* de positions_table.*, je viens d'ajouter pour la clarté).