SET search_path= 'tmp';
DROP TABLE dogcat CASCADE;
CREATE TABLE dogcat
( id serial NOT NULL
, zname varchar
, foo INTEGER
, bar INTEGER
, house_id INTEGER NOT NULL
, PRIMARY KEY (zname,house_id)
);
INSERT INTO dogcat(zname,foo,bar,house_id) VALUES
('Cat',12,4,1)
,('Cat',9,4,2)
,('Dog',8,23,1)
,('Bird',9,54,1)
,('Bird',78,2,2)
,('Bird',29,32,3)
;
-- Carthesian product of the {name,house_id} domains
WITH cart AS (
WITH beast AS (
SELECT distinct zname AS zname
FROM dogcat
)
, house AS (
SELECT distinct house_id AS house_id
FROM dogcat
)
SELECT beast.zname AS zname
,house.house_id AS house_id
FROM beast , house
)
INSERT INTO dogcat(zname,house_id, foo,bar)
SELECT ca.zname, ca.house_id
,fb.foo, fb.bar
FROM cart ca
-- find the animal with the lowes id
JOIN dogcat fb ON fb.zname = ca.zname AND NOT EXISTS
( SELECT * FROM dogcat nx
WHERE nx.zname = fb.zname
AND nx.id < fb.id
)
WHERE NOT EXISTS (
SELECT * FROM dogcat dc
WHERE dc.zname = ca.zname
AND dc.house_id = ca.house_id
)
;
SELECT * FROM dogcat;
结果:
SET
DROP TABLE
NOTICE: CREATE TABLE will create implicit sequence "dogcat_id_seq" for serial column "dogcat.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "dogcat_pkey" for table "dogcat"
CREATE TABLE
INSERT 0 6
INSERT 0 3
id | zname | foo | bar | house_id
----+-------+-----+-----+----------
1 | Cat | 12 | 4 | 1
2 | Cat | 9 | 4 | 2
3 | Dog | 8 | 23 | 1
4 | Bird | 9 | 54 | 1
5 | Bird | 78 | 2 | 2
6 | Bird | 29 | 32 | 3
7 | Cat | 12 | 4 | 3
8 | Dog | 8 | 23 | 2
9 | Dog | 8 | 23 | 3
(9 rows)