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
Related
I'm trying to fill a table with data to test a system.
I have two tables
User
+----+----------+
| id | name |
+----+----------+
| 1 | Majikaja |
| 2 | User 2 |
| 3 | Markus |
+----+----------+
Goal
+----+----------+---------+
| id | goal | user_id |
+----+----------+---------+
I want to insert into goal one record for every user only using their IDs (they have to exists) and some fixed or random value.
I was thinking in something like this:
INSERT INTO Goal (goal, user_id) values ('Fixed value', select u.id from user u)
So it will generate:
Goal
+----+-------------+---------+
| id | goal | user_id |
+----+-------------+---------+
| 1 | Fixed value | 1 |
| 2 | Fixed value | 2 |
| 3 | Fixed value | 3 |
+----+-------------+---------+
I could just write a simple PHP script to achieve it but I wonder if is it possible to do using raw SQL only.
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
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.
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;
I have a dataset which has been grouped using this code:
select
array_to_string(array_agg(DISTINCT "Categories"), ',') as "Categories", "Name", ROW_NUMBER() OVER() as "ID"
from data1
group by "Name"
and it looks like this:
+----+--------+-----------------------------------------+
| ID | Name | Categories |
+----+--------+-----------------------------------------+
| 1 | Class1 | Barry, Steve, Luke, Barry, Barry, Luke |
+----+--------+-----------------------------------------+
| 2 | Class2 | Luke, Barry, Steve |
+----+--------+-----------------------------------------+
| 3 | Class3 | Gerald, Jacqueline, David, Barry, Barry |
+----+--------+-----------------------------------------+
I need to have only the unique values in "Categories". However, in the first row, the database considers Barry, Steve, Luke to be a string, and Barry, Luke to be a string, so using DISTINCT doesn't work to cut out the number of Barrys.
We need to split the string using the comma delimiter, but then re-aggregate it.
The output should look like:
+----+--------+-----------------------------------------+
| ID | Name | Categories |
+----+--------+-----------------------------------------+
| 1 | Class1 | Barry, Steve, Luke |
+----+--------+-----------------------------------------+
| 2 | Class2 | Luke, Barry, Steve |
+----+--------+-----------------------------------------+
| 3 | Class3 | Gerald, Jacqueline, David, Barry |
+----+--------+-----------------------------------------+
You can extract unique values with query like this
select
ID,
Name,
(
select string_agg(c, ',')
from (
select
distinct trim(unnest(string_to_array(Categories, ',')))
) t (c)
) as Categories
from your_table_name;
But it's better to aggregate distinct values while grouping.