【问题标题】:How to concat data columns using loop?如何使用循环连接数据列?
【发布时间】:2020-03-09 06:31:50
【问题描述】:

如何在 Postgres 中使用循环连接列数据?

我有这张桌子:

+------+------+------+--------+--------+--------+
| col1 | col2 | col3 | other1 | other2 | other3 |
+------+------+------+--------+--------+--------+
|    1 |    1 |    1 |      1 |      1 |      1 |
|    2 |    2 |    2 |      2 |      2 |      2 |
+------+------+------+--------+--------+--------+

并且想要连接列(col*)。

预期输出:

+----------------+--------+--------+--------+
| concatedcolumn | other1 | other2 | other3 |
+----------------+--------+--------+--------+
| **1**1**1**    |      1 |      1 |      1 |
| **2**2**2**    |      2 |      2 |      2 |
+----------------+--------+--------+--------+

我可以使用:

select concat('**', col1, '**',col2, '**', col3, '**') as concatedcolumn
      ,other1, other2, other3
from sample_table

我有大约 200 个带有前缀“col”的列,不想拼出 sql 中的所有列。我怎样才能通过循环实现这一点?

【问题讨论】:

  • "我有大约 200 列前缀为 col" 这听起来像是一个有问题的数据库设计。这几乎总是表明该表实际上应该被规范化。如果您不想每次都写concat(或更好的concat_ws()),请使用连接表达式创建一次视图(这可能需要写这个问题的时间)
  • @a_horse_with_no_name 设计 DBA 休假的标志...我不确定哪个部分是更大的危险信号:col* 前缀,还是有 200 列的表?
  • @a_horse_with_no_name 我同意数据库设计最糟糕,但我仍然想知道如何使用循环来做到这一点
  • 好吧,“SQL”没有循环,所以你唯一能做的就是编写一个使用循环的过程(或函数)来使用动态 SQL 生成视图。除了通过编写一次表达式来创建视图之外的任何解决方案都将变得更慢且更难使用。
  • 要么按原样获取表并在客户端代码中编写一个循环来连接结果,要么编写一个循环来创建一个连接列的 SQL 语句。

标签: sql postgresql database-design concatenation dynamic-sql


【解决方案1】:

抛开有问题的数据库设计,您可以动态生成SELECT 语句:

SELECT 'SELECT concat_ws(''**'', '
     || string_agg(quote_ident(attname), ', ') FILTER (WHERE attname LIKE 'col%')
     || ') AS concat_col, '
     || string_agg(quote_ident(attname), ', ') FILTER (WHERE attname NOT LIKE 'col%')
     || ' FROM public.tbl;'                  -- your table name here
FROM   pg_attribute
WHERE  attrelid = 'public.tbl'::regclass     -- ... and here
AND    attnum > 0
AND    NOT attisdropped;

db小提琴here

查询系统目录pg_attribute 或信息架构表columns。我更喜欢系统目录。

在第二步中执行(在验证它是你想要的之后)。

不涉及循环。您可以动态构建语句,但不能(轻松)动态返回结果,因为 SQL 要求在执行时知道返回类型。

concat_ws() 很方便,但它忽略了 NULL 值。我没有专门处理这些。你可能想也可能不想这样做。相关:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 2020-01-16
    • 2018-06-26
    • 1970-01-01
    • 2020-03-18
    • 2022-01-08
    • 1970-01-01
    相关资源
    最近更新 更多