I have a table that is a "tall skinny" fact table:
CREATE TABLE facts(
eff_date timestamp NOT NULL,
update_date timestamp NOT NULL,
symbol_id int4 NOT NULL,
data_type_id int4 NOT NULL,
source_id char(3) NOT NULL,
fact decimal
/* Keys */
CONSTRAINT fact_pk
PRIMARY KEY (source_id, symbol_id, data_type_id, eff_date),
)
I'd like to "pivot" this for a report, so the header looks like this:
eff_date, symbol_id, source_id, datatypeValue1, ... DatatypeValueN
I.e., I'd like a row for each unique combination of eff_date, symbol_id, and source_id.
However, the postgresql crosstab() function only allow on key column.
Any ideas?
crosstab()
expects the following columns from its input query (1st parameter), in this order:row_name
extra
columnscategory
(matching values in 2nd crosstab parameter)value
You don't have a
row_name
. Add a surrogaterow_name
with the window functiondense_rank()
.Your question leaves room for interpretation. Let's add sample rows for demonstration:
Interpretation #1: first N values
You want to list the first N values of
data_type_id
(the smallest, if there are more) for each distinct(source_id, symbol_id, eff_date)
.For this, you also need a synthetic
category
, can be synthesized withrow_number()
. The basic query to produce input tocrosstab()
:Crosstab query:
Results:
Interpretation #2: actual values in column names
You want to append actual values of
data_type_id
to the column namesdatatypeValue1, ... DatatypeValueN
. One ore more of these:5, 6, 7, 23
in the example. Then actual display values can be justboolean
(or the redundant value?). Basic query:Crosstab query:
Result:
dbfiddle here
Related: