W
W
whats2014-05-08 12:14:26
PostgreSQL
whats, 2014-05-08 12:14:26

How to convert a numeric array to a sequence of numbers for IN

Good afternoon. There is a table with such a structure.
0aa46fb80a90620c5978f8804031a1b3bad47bf7
In the fields services and brands there is a type - a numeric array.
In another table there are matches to these keys.
How to make a query that would join this table and convert the identifiers to a textual representation?
Such a request

select *,
//Вложенный запрос который представляет select * from unnest(services) наш массив как последовательность строк, а далее мы в этой последовательности ищем в таблице соответствий текстовое представление и потом опять же агрегируем это все в 1 строку.
(select string_agg(service,',') from autorepair_service where id in(select * from unnest(services))) from autorepair

The request is, to put it mildly, difficult in terms of understanding. Maybe there is an easier way? I did not find any function that would represent an array as a sequence of numbers separated by commas, there is an array to string that converts an array into a string, but then this string cannot be substituted into the IN predicate, an error occurs
operator does not exist: integer = text
. The question itself is of interest. Making one-to-many relationships is not desirable due to query performance.
select *,(
    select string_agg(service,',') 
              from autorepair_service 
    where id=any(services)) 
from autorepair

"Seq Scan on autorepair  (cost=0.00..18772.45 rows=5889 width=693) (actual time=0.143..120.302 rows=5590 loops=1)"
"  SubPlan 1"
"    ->  Aggregate  (cost=3.07..3.08 rows=1 width=36) (actual time=0.021..0.021 rows=1 loops=5590)"
"          ->  Seq Scan on autorepair_service  (cost=0.00..3.05 rows=10 width=36) (actual time=0.003..0.018 rows=29 loops=5590)"
"                Filter: (id = ANY (autorepair.services))"
"                Rows Removed by Filter: 62"
"Total runtime: 120.585 ms"

select *,(select string_agg(service,',') from autorepair_service where id in(select * from unnest(services))) from autorepair

"Seq Scan on autorepair  (cost=0.00..33899.82 rows=5889 width=693) (actual time=0.142..139.699 rows=5590 loops=1)"
"  SubPlan 1"
"    ->  Aggregate  (cost=5.64..5.65 rows=1 width=36) (actual time=0.024..0.024 rows=1 loops=5590)"
"          ->  Hash Semi Join  (cost=2.25..5.41 rows=91 width=36) (actual time=0.009..0.021 rows=29 loops=5590)"
"                Hash Cond: (autorepair_service.id = unnest.unnest)"
"                ->  Seq Scan on autorepair_service  (cost=0.00..1.91 rows=91 width=40) (actual time=0.001..0.005 rows=91 loops=5558)"
"                ->  Hash  (cost=1.00..1.00 rows=100 width=4) (actual time=0.006..0.006 rows=29 loops=5590)"
"                      Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"                      ->  Function Scan on unnest  (cost=0.00..1.00 rows=100 width=4) (actual time=0.002..0.003 rows=29 loops=5590)"
"Total runtime: 140.058 ms"

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Sundukov, 2014-05-08
@alekciy

Actually, the array_to_string function takes a delimiter as the second parameter. An example is right in the documentation: www.postgresql.org/docs/9.3/static/functions-array.html
But in general, you have a problem with the architecture and the incorrect use of the relational database. Because if there are id records of another table, then in the case of a many-to-many relationship, you just need a "linked", intermediate table.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question