PostgreSQL 9.5: comma separated string using string_agg() - postgresql

I have the following table with two fields.
Table:
CREATE TABLE str_agg
(
cola varchar(50),
colb varchar(50)
);
Records:
insert into str_agg values('Alex','Student');
insert into str_agg values('Mak','Student');
insert into str_agg values('John','Teacher');
insert into str_agg values('Tony','Teacher');
I want to display the result in the comma separated format like as shown below:
Expected Result:
result
---------------------------------------------------------
Alex(Student),Mak(Student),John(Teacher),Tony(Teacher)
My try:
select string_agg(cola,'('||colb||'),') Result
from str_agg;
Getting result:
result
---------------------------------------------------------
Alex(Student),Mak(Teacher),John(Teacher),Tony

You are passing the value '('||colb||'),' as the delimiter.
You want:
select string_agg(cola||'('||colb||')', ',') Result
from str_agg;

Related

select/delete can not use default in postgresql?

begin;
create table test101(col1 int default 2, col2 text default 'hello world');
insert into test101 values (1,default);
insert into test101 values (default,default);
insert into test101 values (default,'dummy');
insert into test101 values (5,'dummy');
commit;
update: OK.
update test101 set col2 = default where col1 = 4;
select, delete not OK.
select * from test101 where col1 = COALESCE (col1,default);
delete from test101 where col1 = COALESCE (col1,default);
error code:
ERROR: 42601: DEFAULT is not allowed in this context
LINE 1: delete from test101 where col1 = COALESCE (col1,default);
^
LOCATION: transformExprRecurse, parse_expr.c:285
also tried: delete from test101 where col1 = default;
default value is not easy to find.
Get the default values of table columns in Postgres? Then select/delete operation with default operation is not that weird.
In the question you linked to they do:
SELECT column_name, column_default
FROM information_schema.columns
WHERE (table_schema, table_name) = ('public', 'test101')
ORDER BY ordinal_position;
which produces something like:
column_name | column_default
-------------+---------------------
col1 | 2
col2 | 'hello world'::text
Maybe, you can combine this query with your query? (But I would not recommend it, because ... )

Seperate Input/Output type for a Table in PostgreSQL

I was wondering if it is possible to have the input for a column be one string, with the output being a different string through some dictionary in PostgreSQL. I do know how to use CASE to convert numbers to strings using a SELECT statement, however, I was hoping to create a table such that inputs only require numbers but outputs always give strings.
As an example, for currency USD, CDN and GBP, where 1 = USD, 2 = CDN and 3 = GBP, an example would be:
CREATE TABLE test_table (
currency CHAR (1) CHECK (currency IN ('1','2','3'))
)
Where I could do this:
INSERT INTO test_table (currency)
VALUES ('1')
INSERT INTO test_table (currency)
VALUES ('1')
INSERT INTO test_table (currency)
VALUES ('2')
INSERT INTO test_table (currency)
VALUES ('3')
INSERT INTO test_table (currency)
VALUES ('3')
and the output would look like this:
You can use a CASE expression:
select case currency
when '1' then 'USD'
when '2' then 'CDN'
when '3' then 'GBP'
when '4' then 'EUR'
end as currency
from test_table;
But a better solution would be to create a currency table:
create table currency
(
id integer primary key,
currency_code varchar(3)
);
Then create a foreign key from your base table to the lookup table:
create table test_table
(
...
currency_id integer not null references currency,
...
);
Then use a join to display the code:
select c.code
from test_table t
join currency c on c.id = t.currency_id;

COALESCE types character varying and numeric cannot be matched

I have a table named table1 with columns Gender varchar(10) and Team numeric.
create table table1 (
ID integer
Gender varchar(10),
Team numeric
);
insert into table1 (ID,Gender,Team) values
(1,'M',NULL),
(2,NULL,10),
(3,NULL,6),
(4,''F',NULL),
(5,NULL,3);
I will like to create a new column as Nxt that returns a row that is not null from any of the columns either a string or integer.
The column Nxt will look like: M,10,6,F,3
I tried this:
select coalesce(Gender,Team) as value from table1;
It returns this error:
COALESCE types character varying and numeric cannot be matched
Try to cast the column as text
select coalesce(Gender,Team::text) as value from table1;

insert string into text [] column

I have the following issue.
I will receive input as a text from a webservice to insert into a certain psql table. assume
create table test ( id serial, myvalues text[])
the recieved input will be:
insert into test(myvalues) values ('this,is,an,array');
I want to create a trigger before insert that will be able to convert this string to a text [] and insert it
first Idea that came in my mind was to create a trigger before insert
create function test_convert() returns trigger as $BODY%
BEGIN
new.myvalues = string_to_array(new.myvalues,',')
RETURNS NEW
END; $BODY$ language plpgsql
but this did not work
You can use the string_to_array function to convert your string into an string array within your insert query:
INSERT INTO test ( myvalues )
VALUES ( string_to_array( 'this,is,an,array', ',' ) );
Suppose you receive text in the following format this is an array and you want to convert it to this,is,an,array then you can use string_to_array('this is an array', ' ') and it will be converted. However if you are receiving comma separated then you can just used it.
Creating the Table Schema Like this,
CREATE TABLE expert (
id VARCHAR(32) NOT NULL,
name VARCHAR(36),
twitter_id VARCHAR(40),
coin_supported text[],
start_date TIMESTAMP,
followers BIGINT,
PRIMARY KEY (id)
);
Inserting values like this will help you to insert array,
insert into expert(id, name, twitter_id, coin_supported, start_date, followers) values('9ed1cdf2-564c-423e-b8e2-137eg', 'dev1', 'dev1#twitter', '{"btc","eth"}', current_timestamp, 12);

Select from insert

Is it possible to select from an insert statement? For example:
SELECT id FROM (INSERT INTO table (col1, col2) VALUES (val1, val2));
Where id is an autoincrementing primary key.
It's not possible in such way, because INSERT doesn't return virtual table for SELECT. However you could get id's actual value using currval(regclass) sequence function as:
SELECT currval('yourTableName_id_seq'::regclass);
currval
---------
1
(1 row)
EDIT:
Use RETURNING clause (available since PostgreSQL 8.2):
INSERT INTO yourTableName (col1, col2) VALUES ('aaa', 'bbb') RETURNING id;
id
----
2
(1 row)
"SELECT id FROM mytable WHERE id IS NULL;
"id" has to be an auto_increment column to make it work.
It will return the last_insert_id just as last_insert_id() is expected to do.
example:
mysql> INSERT INTO orders (customer_cust_id, orderdatetime, message, taxrate, shippingprice)
-> SELECT '1', NOW(), null, taxrate, shippingprice FROM customer
-> WHERE cust_id='1';"
http://dev.mysql.com/doc/refman/5.0/en/insert-select.html