我是第一次在MacOSX上使用Postgres 9.3创建数据库。
假设我有表A
和B
。 Table A
开头为空,Table B
为空。我希望表all_names
中的列B
中的条目数等于表number
中每个names
的{{1}},例如表A
下面。因此,B
应包含names
和all_names
计数的每个唯一条目。我还不习惯语法,所以我真的不知道如何去做。 number
列是多余的。
A
birthday
乙
names | number
-------+------------
Carl | 3
Bill | 4
Jen | 2
更新:这是正确的方法吗? 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
答案 0 :(得分:5)
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引入后,您可以使用这个更具面向未来的版本(FROM
列表中的SRF,而不是目标列表中的SRF):
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
的更多信息:
GROUP BY + CASE statement