Postgres交叉表查询每个城市的状态计数

时间:2016-10-14 06:46:49

标签: sql postgresql pivot crosstab

我尝试在Postgres中运行需要交叉表的SQL查询。我以前从未使用过交叉表查询。我的3个表格如下所示:

位置表:

location_id,lang_id,路径

crm_statuses表:

crm_status_id,crm_status_name

store_crm表:

store_crm_id,status(crm_status表的crm_status_id中的引用),location_id(位置表的location_id中的引用)

我希望通过加入store_crm表来获取位置作为列表中的列,或者至少将它们编写为硬编码,因为它们只有3(伦敦,曼彻斯特,利兹)。作为行我想获得crm状态。作为内容,我想计算每个位置有多少活动,非活动和待定商店。活动,非活动,待处理是我的crm_statuses。所需的结果表将具有以下格式。

Status    London  Manchester Leeds
Active    2       4          5
Inactive  6       1          3
Pending   4       4          5

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:1)

您可以将城市硬编码为以下查询中的列:

SELECT 
    * 
FROM crosstab('
        SELECT 
            cs.crm_status_name, 
            l.path, 
            COUNT(*)  
        FROM store_crm AS sc 
        JOIN locations AS l ON (sc.location_id=l.location_id) 
        JOIN crm_statuses AS cs ON (cs.crm_status_id=sc.status) 
        GROUP BY cs.crm_status_name, l.path 
        ORDER BY 1,2
    ', 
    '
        SELECT 
            path 
        FROM 
            locations
    ') AS f("Status" text, "London" text, "Manchester" text, "Leeds" text);

结果:

  Status  | London | Manchester | Leeds 
----------+--------+------------+-------
 Active   | 1      | 2          | 1
 Inactive | 2      | 1          | 4
 Pending  |        | 1          | 1
(3 rows)

如果你有这样的数据库架构:

test=# \d+ locations
                                                    Table "public.locations"
   Column    |  Type   |                            Modifiers                            | Storage  | Stats target | Description 
-------------+---------+-----------------------------------------------------------------+----------+--------------+-------------
 location_id | integer | not null default nextval('locations_location_id_seq'::regclass) | plain    |              | 
 lang_id     | integer |                                                                 | plain    |              | 
 path        | text    |                                                                 | extended |              | 
Indexes:
    "locations_pkey" PRIMARY KEY, btree (location_id)
Referenced by:
    TABLE "store_crm" CONSTRAINT "store_crm_location_id_fkey" FOREIGN KEY (location_id) REFERENCES locations(location_id)

test=# \d+ crm_statuses
                                                       Table "public.crm_statuses"
     Column      |  Type   |                              Modifiers                               | Storage  | Stats target | Description 
-----------------+---------+----------------------------------------------------------------------+----------+--------------+-------------
 crm_status_id   | integer | not null default nextval('crm_statuses_crm_status_id_seq'::regclass) | plain    |              | 
 crm_status_name | text    |                                                                      | extended |              | 
Indexes:
    "crm_statuses_pkey" PRIMARY KEY, btree (crm_status_id)
Referenced by:
    TABLE "store_crm" CONSTRAINT "store_crm_status_fkey" FOREIGN KEY (status) REFERENCES crm_statuses(crm_status_id)

test=# \d+ store_crm
                                                     Table "public.store_crm"
    Column    |  Type   |                            Modifiers                             | Storage | Stats target | Description 
--------------+---------+------------------------------------------------------------------+---------+--------------+-------------
 store_crm_id | integer | not null default nextval('store_crm_store_crm_id_seq'::regclass) | plain   |              | 
 status       | integer |                                                                  | plain   |              | 
 location_id  | integer |                                                                  | plain   |              | 
Indexes:
    "store_crm_pkey" PRIMARY KEY, btree (store_crm_id)
Foreign-key constraints:
    "store_crm_location_id_fkey" FOREIGN KEY (location_id) REFERENCES locations(location_id)
    "store_crm_status_fkey" FOREIGN KEY (status) REFERENCES crm_statuses(crm_status_id)