简体   繁体   English

需要结果集,如下表所示

[英]Need result set as shown from the table below

-- some test tables to start out with:

create table general (
    id serial primary key,
    sno smallint not null,
    name varchar not null,
    qty decimal(12,3) not null );

insert into general 
  (sno,name,qty) 
values
  (1,'a',3),
  (1,'b',4),
  (1,'c',5), 
  (2,'aa',33),
  (2,'bb',44),
  (2,'cc',55);

Result should be in the following format 结果应采用以下格式

{"1",{"1":{"name":"a","qty":"3"},"2":{"name":"b","qty":"4"},"3":{"name":"c","qty":"5"}}
"2",{"1":{"name":"aa","qty":"33"},"2":{"name":"bb","qty":"44"},"3":{"name":"cc","qty":"55"}}}

First, use to_json() from lateral subquery to get (name, qty) pairs as json and add row_number() to number them: 首先,使用横向子查询中的to_json()(name, qty)对作为json并添加row_number()对其编号:

select 
    sno, to_json(t) name_qty,
    row_number() over (partition by sno) rn
from 
    general, 
    lateral (select name, qty) t;

 sno |          name_qty          | rn 
-----+----------------------------+----
   1 | {"name":"a","qty":3.000}   |  1
   1 | {"name":"b","qty":4.000}   |  2
   1 | {"name":"c","qty":5.000}   |  3
   2 | {"name":"aa","qty":33.000} |  1
   2 | {"name":"bb","qty":44.000} |  2
   2 | {"name":"cc","qty":55.000} |  3
(6 rows)

Having this (virtual) result use json_object_agg() two times to aggregate the data in two levels: 具有此(虚拟)结果时,请使用json_object_agg()两次以将数据聚合为两个级别:

select json_object_agg(sno, sno_item)
from (
    select sno, json_object_agg(rn, name_qty) sno_item
    from (
        select 
            sno, to_json(t) name_qty,
            row_number() over (partition by sno) rn
        from 
            general, 
            lateral (select name, qty) t
        ) s
    group by sno
    ) s;

In Postgres 9.5 you can use jsonb_pretty() to get readable result: Postgres 9.5中,您可以使用jsonb_pretty()获得可读的结果:

select jsonb_pretty(json_object_agg(sno, sno_item)::jsonb)
from (
    select sno, json_object_agg(rn, name_qty) sno_item
    from (
        select 
            sno, to_json(t) name_qty,
            row_number() over (partition by sno) rn
        from 
            general, 
            lateral (select name, qty) t
        ) s
    group by sno
    ) s;

        jsonb_pretty        
----------------------------
 {                         +
     "1": {                +
         "1": {            +
             "qty": 3.000, +
             "name": "a"   +
         },                +
         "2": {            +
             "qty": 4.000, +
             "name": "b"   +
         },                +
         "3": {            +
             "qty": 5.000, +
             "name": "c"   +
         }                 +
     },                    +
     "2": {                +
         "1": {            +
             "qty": 33.000,+
             "name": "aa"  +
         },                +
         "2": {            +
             "qty": 44.000,+
             "name": "bb"  +
         },                +
         "3": {            +
             "qty": 55.000,+
             "name": "cc"  +
         }                 +
     }                     +
 }
(1 row)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM