将表中的逗号分隔值替换为select查询中的另一个值(postgres)

时间:2013-10-18 12:21:35

标签: postgresql

我有两个表,表A有ID列,其值以逗号分隔,每个ID值在表B中都有一个表示。

   Table A
+-----------------+
| Name      | ID   |
+------------------
| A1        | 1,2,3|
| A2        | 2    |
| A3        | 3,2  |
+------------------

   Table B
+-------------------+
| ID        | Value |
+-------------------+
| 1        | Apple  |
| 2        | Orange |
| 3        | Mango  |
+-------------------+

我想知道是否有一种有效的方法来进行选择,结果如下所示,

  Name, Value
  A1    Apple, Orange, Mango
  A2    Orange
  A3    Mango, Orange

Any suggestions would be welcome. Thanks.

2 个答案:

答案 0 :(得分:2)

您需要先使用以下内容将table_a“规范化”到新表中:

select name, regexp_split_to_table(id, ',')  id
from table_a;

结果可以加到table_b,然后需要对连接的结果进行分组,以获得逗号分隔的名称列表:

select a.name, string_agg(b.value, ',')
from (
  select name, regexp_split_to_table(id, ',')  id
  from table_a
) a
  JOIN table_b b on b.id = a.id
group by a.name;

SQLFiddle:http://sqlfiddle.com/#!12/77fdf/1

答案 1 :(得分:0)

有两个正则表达式相关的函数可能很有用:

http://www.postgresql.org/docs/current/static/functions-string.html

  • regexp_split_to_table()
  • regexp_split_to_array()

以下代码未经测试,但您可以使用类似的内容来匹配A和B:

select name, value
from A
join B on B.id = ANY(regexp_split_to_array(A.id, E'\\s*,\\s*', 'g')::int[]))

然后,您可以使用array_agg(value),按名称分组,并使用array_to_string()进行格式化。

但有两点说明:

  1. 它不如规范化事物那么有效。
  2. 格式化本身应该在您的视图中进一步完成。