6

MacOSX で Postgres 9.3 を使用して初めてデータベースを作成しています。

AテーブルとがあるとしましょうBA空っぽから始まりB、満たされた状態で始まります。以下の表のように、all_namesテーブルの列のエントリ数をテーブルのfor eachBと等しくしたいと思います。したがって、一意の各エントリとそのカウントを含める必要があります。まだ構文に慣れていないので、どうすればいいのかわかりません。列は冗長です。numbernamesABnamesall_namesnumberbirthday

テーブル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;
4

1 に答える 1

8

元の質問への回答

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);

LATERALPostgres 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マニュアルで説明されているように、ここでは暗黙的です:

LATERALは関数呼び出しFROMアイテムの前に置くこともできますが、この場合、関数式はどのような場合でも以前の FROM アイテムを参照できるため、ノイズ ワードになります。

逆の操作

上記は、単純な集計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:

于 2013-10-02T00:06:00.983 に答える