Reputation: 5
I try to run an sql query in Postgres that requires crosstab. I have never use crosstab queries before. My 3 tables are shown below:
locations TABLE:
location_id , lang_id, path
crm_statuses TABLE:
crm_status_id, crm_status_name
store_crm TABLE:
store_crm_id, status (references in crm_status_id of crm_statuses table), location_id (references in location_id of locations table)
I want to get the locations as columns from the locations table by joining the store_crm table or at least to write them hardcoded as they are only 3 (London,Manchester,Leeds). As rows I want to get the crm statuses. As content I want to count how many active, inactive and pending stores, each location has. The active,inactive,pending are my crm_statuses. The desired results table will have the following format.
Status London Manchester Leeds
Active 2 4 5
Inactive 6 1 3
Pending 4 4 5
How can I achieve that?
Upvotes: 0
Views: 1387
Reputation: 1356
You can hardcode cities as columns in a following query:
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);
With a result:
Status | London | Manchester | Leeds
----------+--------+------------+-------
Active | 1 | 2 | 1
Inactive | 2 | 1 | 4
Pending | | 1 | 1
(3 rows)
If you have database schema like that:
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)
Upvotes: 1