If you add all ColumnsNames (exclude the 'id' Column) after the Tablename, there will be Insert the serial automaticly like:
INSERT INTO animals(nm,typ,tvi,tvf) select nm,typ,tvi,tvf from json_po.....
You can also add a DEFAULT Value in your Column, to set a Default Value if the column is not in the Insert Column-list.
Simple case, static SQL
The non-dynamic solution with crosstab()
for the simple case:
SELECT * FROM crosstab(
'SELECT b.x, f.name, f.x * b.x AS prod
FROM foo f, bar b
ORDER BY 1, 2'
) AS ct (x int, "A" int, "B" int, "C" int, "D" int, "E" int
, "F" int, "G" int, "H" int, "I" int, "J" int);
I order resulting columns by foo.name
, not foo.x
. Both happen to be sorted in parallel, but that's just the simple setup. Pick the right sort order for your case. The actual value of the second column is irrelevant in this query (1-parameter form of crosstab()
).
We don't even need crosstab()
with 2 parameters because there are no missing values by definition. See:
(You fixed the crosstab query in the question by replacing foo
with bar
in a later edit. This also fixes the query, but keeps working with names from foo
.)
Unknown return type, dynamic SQL
Column names and types cannot be dynamic. SQL demands to know number, names and types of resulting columns at call time. Either by explicit declaration or from information in the system catalogs (That's what happens with SELECT * FROM tbl
: Postgres looks up the registered table definition.)
You want Postgres to derive resulting columns from data in a user table. Not going to happen.
One way or the other, you need two round trips to the server. Either you create a cursor and then walk through it. Or you create a temp table and then select from it. Or you register a type and use it in the call.
Or you simply generate the query in one step and execute it in the next:
SELECT $$SELECT * FROM crosstab(
'SELECT b.x, f.name, f.x * b.x AS prod
FROM foo f, bar b
ORDER BY 1, 2'
) AS ct (x int, $$
|| string_agg(quote_ident(name), ' int, ' ORDER BY name) || ' int)'
FROM foo;
This generates the query above, dynamically. Execute it in the next step.
I am using dollar-quotes ($$
) to keep handling of nested quotes simple. See:
quote_ident()
is essential to escape otherwise illegal column names (and possibly defend against SQL injection).
Related:
Best Answer
"without having to define an "as" clause given by a tuple" - no, not possible @a_host_with_no_name