首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将一对多的关系显示为2列-1唯一行(ID &逗号分隔列表)

将一对多的关系显示为2列-1唯一行(ID &逗号分隔列表)
EN

Stack Overflow用户
提问于 2009-04-03 19:30:53
回答 7查看 12.3K关注 0票数 9

我需要类似于这2所以的问题,但使用Informix语法。

我的数据显示如下:

代码语言:javascript
运行
复制
id     codes

63592  PELL
58640  SUBL
58640  USBL
73571  PELL
73571  USBL
73571  SUBL

我想看到它像这样回来:

代码语言:javascript
运行
复制
id     codes 

63592  PELL
58640  SUBL, USBL
73571  PELL, USBL, SUBL

另见group_concat() in Informix

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-04-04 06:42:44

我相信你需要的答案是一个用户定义的聚合,类似于这个:

代码语言:javascript
运行
复制
CREATE FUNCTION gc_init(dummy VARCHAR(255)) RETURNING LVARCHAR;
    RETURN '';
END FUNCTION;

CREATE FUNCTION gc_iter(result LVARCHAR, value VARCHAR(255))
    RETURNING LVARCHAR;
    IF result = '' THEN
        RETURN TRIM(value);
    ELSE
        RETURN result || ',' || TRIM(value);
    END IF;
END FUNCTION;

CREATE FUNCTION gc_comb(partial1 LVARCHAR, partial2 LVARCHAR)
    RETURNING LVARCHAR;
    IF partial1 IS NULL OR partial1 = '' THEN
        RETURN partial2;
    ELIF partial2 IS NULL OR partial2 = '' THEN
        RETURN partial1;
    ELSE
        RETURN partial1 || ',' || partial2;
    END IF;
END FUNCTION;

CREATE FUNCTION gc_fini(final LVARCHAR) RETURNING LVARCHAR;
    RETURN final;
END FUNCTION;

CREATE AGGREGATE group_concat
    WITH (INIT = gc_init, ITER = gc_iter,
          COMBINE = gc_comb, FINAL = gc_fini);

给定一个元素表(称为元素)和一个名为name的列(非常有趣地)包含元素名,以及另一个名为atomic_number的列,此查询将产生以下结果:

代码语言:javascript
运行
复制
SELECT group_concat(name) FROM elements WHERE atomic_number < 10;

Hydrogen,Helium,Lithium,Beryllium,Boron,Carbon,Nitrogen,Oxygen,Fluorine

应用于这个问题,您应该从以下方面获得所需的答案:

代码语言:javascript
运行
复制
SELECT id, group_concat(codes)
    FROM anonymous_table
    GROUP BY id;

代码语言:javascript
运行
复制
CREATE TEMP TABLE anonymous_table
(
    id      INTEGER NOT NULL,
    codes   CHAR(4) NOT NULL,
    PRIMARY KEY (id, codes)
);

INSERT INTO anonymous_table VALUES(63592, 'PELL');
INSERT INTO anonymous_table VALUES(58640, 'SUBL');
INSERT INTO anonymous_table VALUES(58640, 'USBL');
INSERT INTO anonymous_table VALUES(73571, 'PELL');
INSERT INTO anonymous_table VALUES(73571, 'USBL');
INSERT INTO anonymous_table VALUES(73571, 'SUBL');
INSERT INTO anonymous_table VALUES(73572, 'USBL');
INSERT INTO anonymous_table VALUES(73572, 'PELL');
INSERT INTO anonymous_table VALUES(73572, 'SUBL');

SELECT id, group_concat(codes)
    FROM anonymous_table
    GROUP BY id
    ORDER BY id;

这方面的产出是:

代码语言:javascript
运行
复制
58640 SUBL,USBL
63592 PELL
73571 PELL,SUBL,USBL
73572 PELL,SUBL,USBL

添加了额外的数据集,以测试insert序列是否影响结果;它似乎不影响结果(代码按排序顺序排列;我不确定是否有办法改变--反向--该顺序)。

备注:

  1. 这个聚合应该可以用于任何可以转换为VARCHAR(255)的类型,这意味着任何数字或时间类型。Long CHAR列和BLOB类型(字节、文本、blob、CLOB)不被处理。
  2. 普通的LVARCHAR将聚合大小限制在2048字节。如果您认为需要更长的长度,请指定LVARCHAR(10240) ( 10 KiB),例如,在Informix12.10.FC5中指定
  3. ,最大长度似乎是16380;任何更长的长度似乎都会触发SQL -528: Maximum output rowsize (32767) exceeded,这让我感到惊讶。如果需要删除聚合,则可以使用:

如果存在group_concat,则为删除聚合;如果存在gc_fini,则为删除函数;如果存在gc_init,则为删除函数;如果存在gc_iter,则为删除函数;如果存在gc_comb,则为删除函数;

票数 27
EN

Stack Overflow用户

发布于 2009-04-03 20:19:03

我不确定informix,但在MSSQL或Oracle中,您可以使用

解码或案例关键字,将它们连接在一起。然而,这将要求您提前知道所有潜在值,这是脆弱的。

我假设您不喜欢support关键字的原因是informix不支持它?

Oracle还支持按关键字连接,这是可行的,但informix可能不支持。

最好的答案可能是在查询之后,在客户机/数据层构建这个输出。在查询中必须这样做有什么特别的原因吗?

票数 2
EN

Stack Overflow用户

发布于 2021-07-06 08:46:07

Oracle为此类需求提供了列表聚合器功能。

SELECT id, LISTAGG(codes,',') as CODE_LIST FROM <TABLE> GROUP BY id

输出就像

代码语言:javascript
运行
复制
ID     CODE_LIST 
63592  PELL
58640  SUBL,USBL
73571  PELL,USBL,SUBL
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/715350

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档