返回带有附加行号的字符串列

问题描述 投票:0回答:2

我需要从表中获取最大记录数,并将该数字连接到字段名称的末尾,从 1 开始到最大记录数结束:

字段1 cnt
汽车 4
卡车 3

最终结果需要以以下格式导出:

Car|1
Car|2
Car|3
Car|4
Truck|1
Truck|2
Truck|3

我不能使用

RAISE
,因为在这种情况下我需要的不仅仅是一条消息。它必须是数据输出,以便结果可以在下游使用。

sql postgresql row-number
2个回答
1
投票

如果那是你的桌子(符合你的描述):

CREATE TABLE tbl1 (
  tbl_id serial PRIMARY KEY
, field1 text
);

然后

row_number()
作品:

SELECT field1 || '|' || row_number() OVER (PARTITION BY field1)
FROM   tbl1;

如果那是你的表(你的样本数据):

CREATE TABLE tbl2 (
  tbl_id serial PRIMARY KEY
, field1 text
, cnt int
);

然后

generate_series()
完成工作:

SELECT field1  || '|' ||  g
FROM   tbl2, generate_series(1, cnt) g;

小提琴

无论哪种方式都不需要循环和递归。


0
投票

以下是实现上述结果的两种方法。第一个使用递归公用表表达式 (CTE),非常类似于过程语言中的循环。使用数据库时,摆脱过程性思维并采用基于集合的方法是很有用的。第二个查询中演示了基于集合的方法。

WITH RECURSIVE parms(field1, cnt) AS (
  VALUES ('Car', 4),
         ('Truck', 3)
),
cte(field1, cnt, n) AS (
  SELECT parms.field1, parms.cnt, 1 AS n
    FROM parms
   WHERE parms.cnt > 0
  UNION ALL
  SELECT cte.field1, cte.cnt, cte.n + 1 AS n
    FROM cte
   WHERE cte.n < cte.cnt
)
SELECT cte.field1 || '|' || cte.n::text AS result
  FROM cte
 ORDER BY cte.field1, cte.n;
WITH parms(field1, cnt) AS (
  VALUES ('Car', 4),
         ('Truck', 3)
),
c AS (
  SELECT generate_series(1, MAX(parms.cnt)) AS n
    FROM parms
)
SELECT parms.field1 || '|' || c.n::text AS result
  FROM parms
    JOIN c ON c.n <= parms.cnt
 ORDER BY parms.field1, c.n;
© www.soinside.com 2019 - 2024. All rights reserved.