2017-08-14 48 views
2

我正在Postgres 9.6工作。我有资产表:Postgres:通过表计算并加入计数?

CREATE TABLE assets (
    name varchar, 
    company_number varchar 
); 

和公司的一个表(在这两个领域的company_number不无关系,虽然没有正式的外键) - 一个公司可以有很多资产:

CREATE TABLE companies (
    company_number varchar primary key, 
    name varchar 
); 

而公司董事的表,与外国关键公司 - 一个公司可以有很多导演:

CREATE TABLE directors (
    id serial primary key, 
    company_number varchar REFERENCES companies(company_number), 
    person_name varchar 
); 

我可以得到一个排名列表,其中董事都参与了MOS牛逼企业根本,如下:

SELECT person_name, count(*) AS num_companies 
    FROM directors 
    GROUP BY person_name 
    ORDER BY num_companies DESC; 

,我还可以如下得到各董事所拥有的资产数量的排名列表(我认为这是正确的):

SELECT q.person_name, count(*) as num_assets FROM 
(SELECT a.name, c.company_number, c.person_name AS person_name 
    FROM directors d 
    LEFT JOIN assets a 
    ON a.company_number=d.company_number) q 
GROUP BY q.person_name ORDER by num_assets DESC; 

但我怎么会在一个命令中获得两个?换句话说,我想要一份完整的董事名单,包括他们参与的公司数量以及这些公司控制的资产数量。

更新:根据要求,这里的例子SQL创建表和数据:

CREATE TABLE assets (
    name varchar, 
    company_number varchar 
); 
INSERT INTO assets VALUES ('foo', 1), ('bar', 1), ('baz', 2), ('bar', 2), ('fii', 3); 
CREATE TABLE companies (
    company_number varchar primary key, 
    name varchar 
); 
INSERT INTO companies VALUES (1, 'acme corp'), (2, 'intergalactic holdings inc'), (3, 'intergalactic shellco inc'); 
CREATE TABLE directors (
    id serial primary key, 
    company_number varchar REFERENCES companies(company_number), 
    person_name varchar 
); 
INSERT INTO directors(company_number, person_name) VALUES (1, 'arthur dent'), (1, 'trillian'), (2, 'ford prefect'), (3, 'ford prefect'); 

这些都是我想要得到的结果:

person_name,num_companies,num_assets 
ford prefect,2,3 
arthur dent,1,2 
trillian,1,2 
+1

使用http://dbfiddle.uk/?rdbms=postgres_9.6&fiddle=765222fd826584bac50716f974ebecef和岗位所需的输出 – lad2025

+0

@ lad2025感谢请创建示例数据,我与该网站挣扎了一下(无法弄清楚如何清除小提琴中的状态,或编辑新的小提琴!),但已发布更新。 – Richard

回答

1

我会像完整的董事名单,涉及公司数量以及公司控制的资产数量

如果我理解正确的,你需要的是这样的:

select directors.person_name, count(distinct directors.company_number) as company_count, count(distinct name) as asset_count 
from directors 
join assets 
on directors.company_number = assets.company_number 
group by directors.person_name;