如何创建一个将csv字段分解为多行的视图?

时间:2009-09-08 20:18:10

标签: sql postgresql

我的表格结构如下:

create table a (
   a bigint primary key,
   csv varchar(255)
)

我希望能够查询视图(“b”),以便:

select * from b;

产生类似的东西:

a | b
------
1 | A
1 | B
1 | C

对于初始表有一行数据(1,'A,B,C')的情况。

这可以用postgres视图吗?

2 个答案:

答案 0 :(得分:1)

在Postgres 8.4中(我也相信8.3),regexp_split_to_table可用。这可行,但是,我也需要8.1的东西。

这似乎工作正常:

create or replace function split_xmcuser_groups_to_tuples() RETURNS SETOF RECORD AS $$
DECLARE
    r a%rowtype;
    strLen integer;
    curIdx integer;
    commaCnt integer;
    curCSV varchar;
BEGIN
    curIdx := 1;
    commaCnt := 1;
    FOR r IN SELECT * FROM a
    LOOP
        strLen := char_length(r.csv);
        while curIdx <= strLen LOOP
            curIdx := curIdx + 1;
            if substr(r.csv, curIdx, 1) = ',' THEN
                commaCnt := commaCnt + 1;
            END IF;
        END LOOP;
        curIdx := 1;
        while curIdx <= commaCnt LOOP
            curCSV := split_part(r.csv, ',', curIdx);
            if curCSV != '' THEN
                RETURN QUERY select r.a,curCSV;
            END IF;
            curIdx := curIdx + 1;
        END LOOP;
    END LOOP;
    RETURN;
END
$$ LANGUAGE 'plpgsql';

(是的,我知道性能影响和不这样做的原因)

答案 1 :(得分:0)

我想说如果可能的话,这应该在应用程序代码中处理。由于它是一个CSV字段,我假设条目数很小,比方说,每个数据库行<1000。因此,内存和cpu成本不会过于分裂逗号并根据需要进行迭代。

是否有令人信服的理由必须在postgres而不是应用程序中完成?如果是这样,也许您可​​以编写一个psql过程来填充临时表,其中包含拆分每行的结果。以下是使用逗号分割的示例:http://archives.postgresql.org/pgsql-novice/2004-04/msg00117.php