Concat values to string array postgres - postgresql

I want to reach following structure:
["687ccca","da075bd","4194d"]
and try to achieve it like this:
UPDATE table1
SET "ids"= CONCAT ('[', result, ']')
FROM (SELECT string_agg( id::character varying, ', ')
FROM table2 where "name" like '%W11%'
or "name" like '%12%'
or "name" like '%13%'
or "name" like '%5%'
or "name" like '%W9%'
or "name" like '%74%'
) AS result
WHERE "ids"='all';
however I get this:
[("df6bd58d, 26e094b, 637c1, 4a8cf387ff43c5, 9b0bf9f")]
How do I remove ( and ) and add " after each id?

I believe you want to get an JSON array:
demo:db<>fiddle
SELECT
json_agg(your_texts)
FROM
your_table
If you really want text you can cast this result with ::text into a text afterwards:
json_agg(your_texts)::text

Related

UPDATE SET with different value for each row

I have python dict with relationship between elements and their values. For example:
db_rows_values = {
<element_uuid_1>: 12,
<element_uuid_2>: "abc",
<element_uuid_3>: [123, 124, 125],
}
And I need to update it in one query. I made it in python through the query generation loop with CASE:
sql_query_elements_values_part = " ".join([f"WHEN '{element_row['element_id']}' "
f"THEN '{ujson.dumps(element_row['value'])}'::JSONB "
for element_row in db_row_values])
query_part_elements_values_update = f"""
elements_value_update AS (
UPDATE m2m_entries_n_elements
SET value =
CASE element_id
{sql_query_elements_values_part}
ELSE NULL
END
WHERE element_id = ANY(%(elements_ids)s::UUID[])
AND entry_id = ANY(%(entries_ids)s::UUID[])
RETURNING element_id, entry_id, value
),
But now I need to rewrite it in plpgsql. I can pass db_rows_values as array of ROWTYPE or as json but how can I make something like WHEN THEN part?
Ok, I can pass dict as JSON, convert it to rows with json_to_recordset and change WHEN THEN to SET value = (SELECT.. WHERE)
WITH input_rows AS (
SELECT *
FROM json_to_recordset(
'[
{"element_id": 2, "value":"new_value_1"},
{"element_id": 4, "value": "new_value_2"}
]'
) AS x("element_id" int, "value" text)
)
UPDATE table1
SET value = (SELECT value FROM input_rows WHERE input_rows.element_id = table1.element_id)
WHERE element_id IN (SELECT element_id FROM input_rows);
https://dbfiddle.uk/?rdbms=postgres_14&fiddle=f8b6cd8285ec7757e0d8f38a1becb960

How to use a recursive query in a subquery in PostgreSQL

I created a recursive query that returns me a string of the productcategory history (typical parent-child relation:
with recursive productCategoryHierarchy as (
--start with the "anchor" row
select
1 as "level",
pg1.id,
pg1.title,
pg1.parentproductgroup_id
from product_group pg1
where
pg1.id = '17e949b6-85b3-4c87-8f76-ad1e61ea01e1' --parameterize me
union all
-- Get child nodes
select
pch.level +1 as "level",
pg2.id,
pg2.title,
pg2.parentproductgroup_id
from product_group pg2
join productCategoryHierarchy pch on pch.parentproductgroup_id = pg2.id
)
-- Get hierarchy as string
select
CONCAT('',string_agg(productCategoryHierarchy.title, ' > '),'')
from productCategoryHierarchy;
Now I want to use this result in another query as a subquery so that I can use the created string as an attribute in the parent query. Is that possible in Postgres or is there another solution to get a hierarchical tree as string in an attribute?
Are you looking for something like this?
with recursive productcategoryhierarchy as (
...
), aggregated_values as (
select string_agg(productCategoryHierarchy.title, ' > ') as all_titles
from productCategoryHierarchy
)
select ..., (select all_titles from aggregated_values) as all_titles
from ... your main query goes here ..

How to order by a string of numbers separates by dot

I have a query for run over the tree structure, using a CTE way.
The problem is that I use one column called camino for ORDER BY clause. This column is get like that:
---
UNION ALL
SELECT rel.codpadre, rel.codhijo, rel.canpres, depth+1, camino || ''.'' || CAST(rel.posicion AS text) , rel.posicion
FROM ---
This one :
camino || ''.'' || CAST(rel.posicion AS text
gives me a column like that:
0.0.1
0.0.10
0.0.1.0
0.0.1.0.0
0.0.10.0
0.0.1.0.1
0.0.10.1
0.0.2
.......
I need to order by those column, but considering 10 after 9, no after 1.
You can convert the string to an array of integers:
order by string_to_array(camino, '.')::int[]
or
order by string_to_array(concat_ws('.', camino, posicion), '.')::int[]

Variable in comma separated in the IN CLAUSE of SP of DB2 for Z/OS

I have a SP in which I have a In clause like mentioned below
value1 is a Int,Variable1 is varchar
Suppose SP started
Variable1=(value1,value2,value3)--getting from another table
Select * from tableA where Column1 in (Variable1).
The just above statement is not working ,needed a work around for this ,Please help
Here is a small example of using an XML list to select an arbitrary number of values:
SELECT * FROM "tableA"
WHERE "Column1" IN (
SELECT * FROM
XMLTABLE('$X/set/row' PASSING XMLPARSE('
<set>
<row item="1"/>
<row item="2"/>
<row item="3"/>
<!-- add as many "row" as you need here -->
</set>
')
AS "X"
COLUMNS
"item" INT PATH '#item'
) AS X
)
Then you can parameterize the query, where ? is a parameter of type XML
SELECT * FROM "tableA"
WHERE "Column1" IN (
SELECT * FROM
XMLTABLE('$X/set/row' PASSING ? AS "X" COLUMNS "item" INT PATH '#item') AS X
)

getting formatted column value in postgres

I have a column in my table having values of format:
COURSE_214/MODULE_5825/SUBMODULE_123/..../GOAL_124/ACTIVITY_125.
I need value for goal i.e 124 from goal_124. I am planning to use 'regexp_split_to_array' but don't know how to use elements from array.
I am using postgres 9.2.
You can use split_part like so:
select split_part(split_part('COURSE_214/MODULE_5825/SUBMODULE_123/..../GOAL_124/ACTIVITY_125', '/GOAL_', 2), '/', 1)
i.e.
select split_part(split_part(fieldname, '/GOAL_', 2), '/', 1)
Result:
124
Using json_object():
select json_object(string_to_array(translate(params, '_', '/'), '/'))
from test
json_object
------------------------------------------------------------------------------------------------
{"COURSE" : "214", "MODULE" : "5825", "SUBMODULE" : "123", "GOAL" : "124", "ACTIVITY" : "125"}
(1 row)
select json_object(string_to_array(translate(params, '_', '/'), '/'))->>'GOAL' as goal
from test
goal
------
124
(1 row)
The column has a format suitable for json. I would suggest to change the type of the column to jsonb. The first query may be used as a converter.
After the conversion you would access the parameters in an easy way, e.g.:
select *
from test
where params->>'COURSE' = '214'
and (params->>'GOAL')::int > 120;
Simple select of all GOAL_ parameters (if there are more than one)
select ltrim(elem, 'GOAL_')
from (
select unnest(string_to_array(params, '/')) elem
from test
) sub
where elem like 'GOAL_%'
You may try using regular expressions, getting the string between slashes
select substring(your_column from '^.*/(.*)/.*$') from your_table
If you expect to find in that part the GOAL value, use
select substring(your_column from '/GOAL_(.*)/') from your_table