How to combine multiple jsonb columns into a generated column
For single column the following statement works
alter table r
add column txt TEXT GENERATED ALWAYS as (
doc->'contact'->>'name'
) stored;
I tried the following statement without success,
SQL Error [42883]: ERROR: operator does not exist: text -> unknown
alter table r
add column txt TEXT GENERATED ALWAYS as (
doc->'contact'->>'name' || ' ' || doc->'contact'->>'phone'
) stored;
Answer:
alter table r
add column txt TEXT GENERATED ALWAYS as (
(doc->'contact'->>'name') || ' ' || (doc->'contact'->>'phone')
) stored;
I want to insert text data into a Postgres bytea column using the concat function or the || operator. I am getting an error
column "name" is of type bytea but expression is of type text
create table test(
name bytea
);
insert into test(name) values(concat('abac-' , 'test123'));
insert into test(name) values('aa' || 'bb');
I am executing the insert inside a stored procedure. If want to add the argument like
(concat('abac-' , row.name , 'test123'));
How do I do it?
Perform a type cast after concatenating the values:
INSERT INTO test (name)
VALUES (CAST('abac-' || row.name || 'test123' AS bytea));
Note: The difference between || and concat is how they behave with NULLs.
You need to cast both strings to bytea, for example:
insert into test(name) values('aa'::bytea || 'bb'::bytea);
I am trying to insert data into a postgres table from a remote database table. I have written the following query for this purpose but I am getting following error.
'[Code: 0, SQL State: 42601] ERROR: syntax error at or near "table"
Position: 13 [Script position: 141 - 146]'
create table clintrial_EP_map.lead_sponsors (row_id SERIAL, lead_sponsors character varying)
insert into table clintrial_ep_map (lead_sponsors)
( select
*
from
dblink('dbname=x user=x host=x password=x port = x',
'
SELECT
distinct bm_dimt_clinical_trial.lead_sponsor
FROM
dwh_prod.bm_dimt_clinical_trial
where dataset_version_id = xx and lead_sponsor_class = ''xx''
'
) as ls (
lead_sponsor character varying
)
)
;
Please see, the following query is giving me desired output.
select
*
from
dblink('dbname=x user=x host=x password=x port = x',
'
SELECT
distinct bm_dimt_clinical_trial.lead_sponsor
FROM
dwh_prod.bm_dimt_clinical_trial
where dataset_version_id = xx and lead_sponsor_class = ''xx''
'
) as ls (
lead_sponsor character varying
)
;
I am not able to find a syntax error near 'table' in my insert query. Any suggestions here will be really helpful.
Thanks
Your query has two issues.
First: Create table is not ending with ; i am hoping that is typo and Second: Your insert statement is referring to schema name instead of schema qualified table name. And also using keyword 'table' in insert statment which is not required. So your correct query will be
create table clintrial_EP_map.lead_sponsors (row_id SERIAL, lead_sponsors character varying);
and
insert into clintrial_EP_map.lead_sponsors (lead_sponsors)
( select * from
dblink('dbname=x user=x host=x password=x port = x',
'SELECT
distinct bm_dimt_clinical_trial.lead_sponsor
FROM
dwh_prod.bm_dimt_clinical_trial
where dataset_version_id = xx and lead_sponsor_class = ''xx''
'
) as ls (lead_sponsor character varying)
);
How do I count the number of distinct elements in an array object, created by ARRAY_AGG() in PostgresQL? Here's a toy example for discussion purposes:
SELECT ARRAY_AGG (first_name || ' ' || last_name) actors
FROM film
I have tried ARRAY_LENGTH(), LENGTH(), etc., like so:
SELECT ARRAY_LENGTH(a.actors)
FROM (SELECT ARRAY_AGG (first_name || ' ' || last_name) actors
FROM film) a;
But I get an error:
function array_length(integer[]) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Position: 208
So I tried (2):
SELECT ARRAY_LENGTH( CAST(COALESCE(a.actors, '0') AS integer) )
FROM (SELECT ARRAY_AGG (first_name || ' ' || last_name) actors
FROM film) a;
but I get the error:
malformed array literal: "0"
Detail: Array value must start with "{" or dimension information.
Position: 119
the function array_length(anyarray, int) require two elements, array and dimension for example:
Select array_length(array[1,2,3], 1);
Result:
3
If you are only dealing with a single dimension array, cardinality() is easier to use:
SELECT cardinality(ARRAY_LENGTH(a.actors))
FROM (
SELECT ARRAY_AGG (first_name || ' ' || last_name) actors
FROM film
) a;
Code below from how to preserve column names on dynamic pivot is used to create dynamic pivot table.
If source table contains no data, sql error occurs since create table column list end with comma (there are no pivot columns).
How to fix this so that empty table is returned ?
To reproduce, remove insert commands
insert into sales values ( '2016-1-1', 'Ø 12.3/3mm', 2);
insert into sales values ( '2016-1-1', '+-3,4%/3mm', 52);
insert into sales values ( '2016-1-3', '/3,2m-', 246);
from code.
testcase:
create temp table sales ( saledate date, productname char(20), quantity int );
insert into sales values ( '2016-1-1', 'Ø 12.3/3mm', 2);
insert into sales values ( '2016-1-1', '+-3,4%/3mm', 52);
insert into sales values ( '2016-1-3', '/3,2m-', 246);
do $do$
declare
voter_list text;
begin
create temp table myyk on commit drop as
select saledate as kuupaev,
format ('"%s"', replace (upper(productname), ' ', '')) as tootjakood,
sum(quantity)::int as kogus
from sales
group by 1,2
;
drop table if exists pivot;
voter_list := (
select string_agg(distinct tootjakood, ' ' order by tootjakood) from myyk
);
execute(format('
create table pivot (
kuupaev date,
%1$s
)', (replace(voter_list, ' ', ' integer, ') || ' integer')
));
execute (format($f$
insert into pivot
select
kuupaev,
%2$s
from crosstab($ct$
select
kuupaev,tootjakood,kogus
from myyk
order by 1
$ct$,$ct$
select distinct tootjakood
from myyk
order by 1
$ct$
) as (
kuupaev date,
%4$s
);$f$,
replace(voter_list, ' ', ' + '),
replace(voter_list, ' ', ', '),
'',
replace(voter_list, ' ', ' integer, ') || ' integer' -- 4.
));
end; $do$;
select * from pivot;
Postgres 9.1 is used.
Insert an exception handler at the bottom of the DO block body. You can silently ignore errors and create dummy pivot table:
...
exception
when others then
drop table if exists pivot;
create table pivot ("No data" text);
end; $do$;
or raise an exception with your own error message:
...
exception
when others then
drop table if exists pivot;
raise exception 'There is no data in the source dataset.'
end; $do$;
You can also use if-then-else statement:
...
drop table if exists pivot;
if (select count(*) from myyk) > 0 then
voter_list := (
select string_agg(distinct tootjakood, ' ' order by tootjakood) from myyk
);
...
...
else
create table pivot ("No data" text);
end if;
end; $do$;