2016-09-16 65 views
0

我在父表中有一行,但我沒有在子項中創建副本。從documentationPostgreSQL的繼承:將父項的行插入到子項中

擴展的例子:

CREATE TABLE cities (
    idcity   serial PRIMARY KEY, 
    name   text, 
    population  float, 
    altitude  int  -- in feet 
); 

INSERT INTO cities VALUES (1, 'San Francisco', 7.24E+5, 63); 
INSERT INTO cities VALUES (2, 'Las Vegas', 2.583E+5, 2174); 
INSERT INTO cities VALUES (3, 'Mariposa', 1200, 1953); 
INSERT INTO cities VALUES (4, 'Sacramento', 3.694E+5, 30); 

-- The capitals table inherits from cities table. 
CREATE TABLE capitals (
    state   char(2) 
) INHERITS (cities); 

比方說,我剛剛學會薩克拉門託是一種資本,所以我想在我capitals表。 如果我使用正常的INSERT INTO capitals,我會在城市中獲得重複值,但這不是很有用。

INSERT INTO capitals VALUES (4, 'Sacramento', 3.694E+5, 30, 'CA'); 

SELECT * FROM cities WHERE idcity = 4; 

idcity | name  | population | altitude 
-------+------------+------------+--------- 
4  | Sacramento | 369400  | 30 
4  | Sacramento | 369400  | 30 

(如文檔中規定,繼承導致具有主鍵重複的價值,我會避免與FROM ONLY,但是這不是我的問題。)

我想我可以有capitals上的觸發器在我插入子進程時刪除父行,但是沒有內置的方法來執行此操作?

+1

不,因爲你打破了那裏的繼承邏輯。使城市成爲資本意味着它不再是城市嗎?但是如果你真的需要實現這個目標,觸發就是要走的路。 –

+0

@AlexeySoshin我的意思是相反的:我想讓一個城市成爲一個首都,而不會改變它作爲一個城市(名稱,人口,海拔......)的任何東西。我怎麼能這樣做? – Victor

+0

但是,這正是你現在所擁有的,沒有任何觸發器。 –

回答

1

您可以從解釋計劃看到select * from cities基本上是一個UNION ALL:

explain 
select * 
from cities; 

Append (cost=0.00..21.27 rows=1027 width=4) 
    -> Seq Scan on cities (cost=0.00..2.07 rows=107 width=4) 
    -> Seq Scan on capitals (cost=0.00..19.20 rows=920 width=4) 

explain select idcity from only cities 
union all 
    select idcity from capitals 

Append (cost=0.00..21.27 rows=1027 width=4) 
    -> Seq Scan on cities (cost=0.00..2.07 rows=107 width=4) 
    -> Seq Scan on capitals (cost=0.00..19.20 rows=920 width=4) 

因此你的選擇要麼使用select distinct * from cities,這將是類似於:

select idcity from only cities 
union 
select idcity from capitals 

或使用觸發,正如我們在上面的評論中所討論的。但是我們認爲觸發在這個特定情況下是沒有意義的。

所以,我沒有發現實現這一點的內置方式,除非使用不同的方式。