2009-08-07 58 views

回答

49

沒有,有沒有直接的方法來做到這一點。這是有原因的 - 每個查詢都應該列出所需的所有字段,而不管它們需要什麼順序(和格式等),從而使得一個表中列的順序無關緊要。

如果你真正需要做的,我能想到一個變通方法:

  • 轉儲和保存表的問題的說明(使用pg_dump --schema-only --table=<schema.table> ...
  • 要將其添加你想要的列在已保存的定義
  • 在已保存的定義重命名錶,以便與舊錶的名稱相沖突,當您試圖創建
  • 創建新表使用這個定義
  • 使用'INSERT INTO <new_table> SELECT field1,field2,<default_for_new_field>,field3,... FROM <old_table>'來填充新表格中的數據。
  • 重命名舊錶
  • 新表重命名爲原來的名稱
  • 最終刪除舊,重命名錶,你要確保一切是正常
+12

「每個查詢都應該以任何順序列出它所需的所有字段」→這很容易,只要你不需要與其他人一起工作即可。 – 2015-05-24 04:36:01

+9

列的順序可能與使用數據庫的應用程序無關。如果在調查表結構或數據時按順序列出相似的列,那麼DBA看起來會更好。我個人覺得很煩人,我有幾個時間列,因爲他們稍後添加而沒有進行可視化分組。僅僅因爲Postgres不支持在特定位置添加列而重新創建數據庫對我來說感覺很奇怪,特別是如果其背後的原因是強制人們在他們的查詢中明確列出列。要清楚:我不相信這是原因。 – Dynom 2016-03-11 09:36:17

-3

後列的順序是完全不相關在關係數據庫中

是的。

例如,如果你使用Python,你會怎麼做:

cursor.execute("SELECT id, name FROM users") 
for id, name in cursor: 
    print id, name 

或者,你會怎麼做:

cursor.execute("SELECT * FROM users") 
for row in cursor: 
    print row['id'], row['name'] 

但是,沒有理智的人會永遠使用這樣的定位結果:

cursor.execute("SELECT * FROM users") 
for id, name in cursor: 
    print id, name 
+9

這完全是不真實的。這適用於選擇您展示的方式,但在指定列名稱的情況下看到插入內容並不罕見,例如插入表值(1,2,3,4)。如果表列順序發生更改,那麼插入查詢的樣式將失敗。還值得注意的是,不是每個開發者都是理智的,如果你碰巧繼承了其中一個開發者的代碼...... – 2013-08-27 22:39:51

21

列的順序並非無關緊要,將固定寬度的列放在表的前面可以選擇縮小數據的存儲佈局,還可以在應用程序代碼之外更輕鬆地處理數據。

PostgreSQL不支持更改列排序(請參閱PostgreSQL wiki上的Alter column position);如果表是相對孤立的,最好的辦法是重新創建表:

CREATE TABLE foobar_new (...); 
INSERT INTO foobar_new SELECT ... FROM foobar; 
DROP TABLE foobar CASCADE; 
ALTER TABLE foobar_new RENAME TO foobar; 

如果你有很多的觀點或對錶定義的約束,可以在新列後重新添加所有列和刪除原始列(請參閱PostgreSQL wiki中的示例)。

-1

@Jeremy Gustie的解決方案上面的差不多的工作,但會做錯誤的事情,如果有序關閉(或如果重新排序的序使不兼容的類型匹配完全失敗)。試試看:

CREATE TABLE test1 (one varchar, two varchar, three varchar); 
CREATE TABLE test2 (three varchar, two varchar, one varchar); 
INSERT INTO test1 (one, two, three) VALUES ('one', 'two', 'three'); 
INSERT INTO test2 SELECT * FROM test1; 
SELECT * FROM test2; 

結果顯示問題:

testdb=> select * from test2; 
three | two | one 
-------+-----+------- 
one | two | three 
(1 row) 

您可以在插入指定的列名解決這個問題:

INSERT INTO test2 (one, two, three) SELECT * FROM test1; 

這就給了你什麼你真想:

testdb=> select * from test2; 
three | two | one 
-------+-----+----- 
three | two | one 
(1 row) 

問題出現在你有遺產不這樣做時,正如我在我對peufeu的回覆評論中所指出的那樣。

更新:在我看來,通過在SELECT子句中指定列名,您可以對INSERT子句中的列名執行相同的操作。你只需要重新排序到目標表匹配序:

INSERT INTO test2 SELECT three, two, one FROM test1; 

而且你當然可以做兩個非常明確的:

INSERT INTO test2 (one, two, three) SELECT one, two, three FROM test1; 

,將給你相同的結果上面,列值適當匹配。

-2

@米倫A.拉德夫

從具有列一組順序無關的需求不是由拉他們查詢始終定義。在pg_fetch_row的值中不包含關聯的列名稱,因此需要由SQL語句定義列。

一個簡單select * from需要的表結構的先天知識,有時會造成問題,如果列的順序要改變。

使用pg_fetch_assoc是一種更可靠的方法,因爲您可以引用列名稱,因此可以使用簡單的select * from

+1

這種需求並非無關緊要。當我手動檢查數據時,我想簡單地使用'SELECT *',但我希望更有趣的列先來。 – maaartinus 2014-02-19 06:38:43

相關問題