Store an array field in a new table column - postgresql

I have a table like this
| id | amenities | owner |
|----|--------------------------|----------------|
| 1 | {tv, hairdryer, iron} | Chris Houghton |
| 2 | {tv, aircondition, iron} | Matt Quinn |
I want to store the car table values in a new column "amenity_name" of another table "Amenity" but without UNNEST.
Here is what I tried so far
UPDATE public."Amenity" set amenity_name = (
SELECT amenities
FROM public."Listing" as l
cross join regexp_split_to_table(l.amenities , ',') as amenity_name
);
What is wrong with this code.

Related

Reset column with numeric value that represents the order when destroying a row

I have a table of users that has a column called order that represents the order in they will be elected.
So, for example, the table might look like:
| id | name | order |
|-----|--------|-------|
| 1 | John | 2 |
| 2 | Mike | 0 |
| 3 | Lisa | 1 |
So, say that now Lisa gets destroyed, I would like that in the same transaction that I destroy Lisa, I am able to update the table so the order is still consistent, so the expected result would be:
| id | name | order |
|-----|--------|-------|
| 1 | John | 1 |
| 2 | Mike | 0 |
Or, if Mike were the one to be deleted, the expected result would be:
| id | name | order |
|-----|--------|-------|
| 1 | John | 1 |
| 3 | Lisa | 0 |
How can I do this in PostgreSQL?
If you are just deleting one row, one option uses a cte and the returning clause to then trigger an update
with del as (
delete from mytable where name = 'Lisa'
returning ord
)
update mytable
set ord = ord - 1
from del d
where mytable.ord > d.ord
As a more general approach, I would really recommend trying to renumber the whole table after every delete. This is inefficient, and can get tedious for multi-rows delete.
Instead, you could build a view on top of the table:
create view myview as
select id, name, row_number() over(order by ord) ord
from mytable

Access column array and store it in a new table

I have a table like this:
| id | cars | owner |
|----|--------------------------|----------------|
| 1 | {tesla, bmw, mercedes} | Chris Houghton |
| 2 | {toyota, bmw, fiat} | Matt Quinn |
Is there a way to access the car table array DISTINCT values and store them in a new table without duplicate values?
I want this table
| brands |
|--------|
| tesla |
| bmw |
|mercedes|
| toyota |
| fiat |
I believe you are looking for this kind of statement.
SELECT
DISTINCT
table_array.array_unnest
FROM (
SELECT
UNNEST(cars)
FROM
<table>
) AS table_array(array_unnest)
see demo
This indeed works but how can I store them for example in a column
"brand" of a table Manufactures.
INSERT INTO
Manufactures
(brand)
SELECT
DISTINCT
table_array.array_unnest
FROM (
SELECT
UNNEST(cars)
FROM
<table>
) AS table_array(array_unnest)
see demo

How to aggregate Postgres table so that ID is unique and column values are collected in array?

I'm not sure how to call what I'm trying to do, so trying to look it up didn't work very well. I would like to aggregate my table based on one column and have all the rows from another column collapsed into an array by unique ID.
| ID | some_other_value |
-------------------------
| 1 | A |
| 1 | B |
| 2 | C |
| .. | ... |
To return
| ID | values_array |
-------------------------
| 1 | {A, B} |
| 2 | {C} |
Sorry for the bad explanation, I'm really lacking the vocabulary here. Any help with writing a query that achieves what's in the example would be very much appreciated.
Try the following.
select id, array_agg(some_other_value order by some_other_value ) as values_array from <yourTableName> group by id
You can also check here.
See Aggregate Functions documentation.
SELECT
id,
array_agg(some_other_value)
FROM
the_table
GROUP BY
id;

Grouping fields from one to many relationship in postgres

I need to group fields in a child table in one query in postgres.
I have following data
Stores:
| id | name |
|----|------|
| 1 | abcd |
Features:
| id | store | name | other |
|----|-------|------|-------|
| 1 | 1 | door | metal |
| 2 | 1 | fork | green |
I've got to this query
SELECT
stores.id,
stores.name,
concate_ws(',', features.id, features.name, features.other)
FROM stores
LEFT JOIN features
ON(features.store=stores.id)
WHERE stores.id =1
GROUP BY stores.id, features.id;
This is best I've got so far but yields 2 tuples
1, abcd, (1,door,metal)
1, abcd, (2,fork,green)
I'd like to be able to get one row with the features '|' concatenated like so
1, abcd ,(1,door,metal|2,fork,green)
Use string_agg():
SELECT stores.id,
stores.name,
string_agg(concate_ws(',', features.id, features.name, features.other), '|')
FROM stores
LEFT JOIN features ON features.store=stores.id
WHERE stores.id =1
GROUP BY stores.id, stores.name;

insert uid into column based

I have two tables in postgresql looks something like below. please help me with the query to insert into table 1uid column based on column name2.
table 1 table 2
|uid|name1| |uid|name2|table 1uid|
| 1 | a | | 1 | b | |
| 2 | b | | 2 | C | |
| 3 | c | | 3 | a | |
The keyword you need to look for is Update (which changes existing rows). Insert is for creating brand new rows.
But for your particular case, something along the lines of:
update table2 set table1uid = (select uid from table1 where table1.name1 = table2.name2)