【问题标题】:Insert multiple rows in one table based on number in another table根据另一个表中的数字在一个表中插入多行
【发布时间】:2013-10-08 06:55:21
【问题描述】:

我是第一次在 MacOSX 上使用 Postgres 9.3 创建数据库。

假设我有表 ABA 开始是空的,B 是填充的。我希望表 B 中的列 all_names 中的条目数等于表 A 中每个 namesnumber,如下表 B。因此names 应该包含来自all_namesnumber 其计数的每个唯一条目。我还不习惯语法,所以我真的不知道该怎么做。 birthday 列是多余的。

A

names | number
------+--------
Carl  | 3
Bill  | 4
Jen   | 2

B

 all_names | birthday
-----------+------------
Carl       | 17/03/1980
Carl       | 22/08/1994
Carl       | 04/09/1951
Bill       | 02/12/2003
Bill       | 11/03/1975
Bill       | 04/06/1986
Bill       | 08/07/2005
Jen        | 05/03/2009
Jen        | 01/04/1945

这是正确的方法吗?

insert into a (names, number)
select b.all_names, count(b.all_names)
from b
group by b.all_names;

【问题讨论】:

    标签: sql postgresql relational-database generate-series


    【解决方案1】:

    回答原问题

    Postgres 允许集合返回函数 (SRF) 将行相乘。 generate_series()是你的朋友:

    INSERT INTO b (all_names, birthday)
    SELECT names, current_date -- AS birthday ??
    FROM  (SELECT names, generate_series(1, number) FROM a);
    

    自从引入LATERAL in Postgres 9.3 以来,您可以坚持使用标准SQL:SRF 从SELECT 移动到FROM 列表:

    INSERT INTO b (all_names, birthday)
    SELECT a.names, current_date -- AS birthday ??
    FROM   a, generate_series(1, a.number) AS rn
    

    LATERAL 在这里是隐含的,正如in the manual 解释的那样:

    LATERAL 也可以在函数调用 FROM 项之前,但在这种情况下 它是一个噪声词,因为函数表达式可以参考 无论如何,之前的 FROM 项。

    反向操作

    以上是一个简单的aggregate count()的逆运算(近似):

    INSERT INTO a (name, number)
    SELECT all_names, count(*)
    FROM   b
    GROUP  BY 1;
    

    ...适合您更新的问题。

    注意count(*)count(all_names) 之间的细微差别。无论如何,前者计算所有行,而后者只计算all_names IS NOT NULL 的行。如果您的列all_names 定义为NOT NULL,则两者返回相同,但count(*) 更短且更快。

    关于GROUP BY 1

    【讨论】:

    • create table b (names text, number int); insert into b (names) values ('bill'), ('bill'), ('jen'); select b.names from b, generate_series(1, b.number) as rn; 为什么这不起作用?谢谢。
    • @jO.:在您的示例中,number 为 NULL。所以generate_series() 不会生成任何行。插入 number 的值。
    • 感谢您的回复和帮助。我已经更新了我的问题。我意识到我所追求的可能还不够清楚,甚至认为你的答案第一次对我有用 - 奇怪的是,generate_series() 不会与 NULL 一起使用。我一定是输入了错误的数据。非常感谢!
    • @jO.:基本上你是在逆运算之后,你的解决方案应该可以工作。我在答案中添加了一些内容。
    • 谢谢!非常感谢您的帮助和澄清!
    猜你喜欢
    • 2023-03-09
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多