Как агрегировать столбец на основе другого столбца в postgres - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть база данных, где у меня есть данные для компаний, поступающих из разных источников.Я хочу иметь возможность выбирать данные для конкретной информации о компании (поля) и объединять их в одну запись для каждой компании.Я хочу сделать это без использования третьего обычного хранилища форм, чтобы у меня все еще была ссылочная целостность.Я также хочу сделать операцию слияния динамически, без специального кодирования для столбцов.

Пример данных и запроса:

create table test2.company(
identifier int not null
,name varchar(100) null
,marketcap int null --in millions
,field varchar(100) not null
);

insert into test2.company(identifier, name, marketcap,field) values
(1,'Apple',1, 'name')
,(1,'Aplle',1000000,'marketcap')
;

select * from test2.company;

- результат

----------------------------------------------
| identifier | name  | marketcap | field     |
| ---------- | ----- | --------- | --------- |
| 1          | Apple | 1         | name      |
| 1          | Aplle | 1000000   | marketcap |
----------------------------------------------

Лучшее, что я когда-либо придумал:

with x1 as (select
    c.identifier
    ,case when c.field = 'name' then c.name else null end as name
    ,case when c.field = 'marketcap' then marketcap else null end as marketcap
    from test2.company c
)
, x2 as (select 
    x1.identifier
    ,string_agg(x1.name,'') as name
    ,sum(x1.marketcap) as marketcap
    from x1
    group by x1.identifier
)
select * from x2;

- результат

----------------------------------
| identifier | name  | marketcap |
| ---------- | ----- | --------- |
| 1          | Apple | 1000000   |
----------------------------------

Как видите, мне пришлось специально кодировать столбцы.Там, где тип данных был числом, мне приходилось использовать сумму против строки_агг.

Есть ли способ сделать это универсальным?

1 Ответ

0 голосов
/ 16 ноября 2018

Полагаю, вот как это может быть родовым -

with x1 as (select
    c.identifier
    ,c.field
    ,string_agg(c.name, '') as name
    ,sum(c.marketcap) as marketcap
    from test2.company c
    group by c.identifier, c.field
)
select x.identifier, 
       (select name from x1 a where a.field = 'name' and a.identfier = x.identifier) as name, 
       (select marketcap from x1 b where b.field = 'marketcap' and b.identfier = x.identifier) as marketcap 
       from x1 x;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...