1. 程式人生 > >postgresql 基礎

postgresql 基礎

PostgreSQL 基本語法

這裡記錄些PostgreSQL的基本語法,內容基本來自 [PostgreSQL 9.5.3 中文手冊]

建立資料庫

CREATE DATABASE mydb;
  
  • 1

刪除資料庫

DROP DATABASE mydb;
  
  • 1

建立表

CREATE TABLE weather (
    city            varchar(80),
    temp_lo         int,           -- 最低溫度
    temp_hi         int
, -- 最高溫度 prcp real, -- 溼度 real是一種用於儲存單精度浮點數的型別 date date );
CREATE TABLE cities ( name varchar(80), location point );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

刪除表

DROP TABLE cities;
DROP TABLE weather
  • 1
  • 2

在表中增加行

INSERT INTO weather VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');
INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
INSERT INTO weather (city, temp_lo, temp_hi, prcp, date) 
    VALUES ('San Francisco', 43, 57, 0.0, '1994-11-29');
INSERT INTO weather (date, city, temp_hi, temp_lo) 
    VALUES
('1994-11-29', 'Hayward', 54, 37);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

查詢

SELECT * FROM weather;
SELECT * FROM cities;
SELECT city, temp_lo, temp_hi, prcp, date FROM weather;
--可以在選擇列表中寫任意表達式
SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;
--檢索舊金山的下雨天的天氣:
SELECT * FROM weather WHERE city = 'San Francisco' AND prcp > 0.0;
--要求返回的查詢結果是排好序的
SELECT * FROM weather ORDER BY city;
SELECT * FROM weather ORDER BY city, temp_lo;
--消除重複的行:
SELECT DISTINCT city FROM weather;
SELECT DISTINCT city FROM weather ORDER BY city;
--連線查詢,一個同時訪問同一個或者不同表的多個行的查詢叫連線查詢。
SELECT * FROM weather, cities WHERE city = name;
SELECT city, temp_lo, temp_hi, prcp, date, location
    FROM weather, cities
    WHERE city = name;
SELECT weather.city, weather.temp_lo, weather.temp_hi,
       weather.prcp, weather.date, cities.location
    FROM weather, cities
    WHERE cities.name = weather.city;
--使用內連線查詢
SELECT * FROM weather INNER JOIN cities ON (weather.city = cities.name);
--觀察結果集沒有城市Hayward的結果行。這是因為連線查詢會忽略各表中不匹配行
--如果需要顯示錶中不匹配行,那就使用外連線查詢
SELECT * FROM weather LEFT OUTER JOIN cities ON (weather.city = cities.name);
--這個查詢是一個左外連線, 因為在連線操作符左部的表中的行在輸出中至少要出現一次, 而在右部的表的行只有在能找到匹配的左部錶行是才被輸出。如果輸出的左部表的行沒有對應匹配的右部表的行,那麼右部錶行的列將填充空值(null)。
--我們也可以把一個表和自己連線起來。這叫做自連線
SELECT W1.city, W1.temp_lo AS low, W1.temp_hi AS high,
    W2.city, W2.temp_lo AS low, W2.temp_hi AS high
    FROM weather W1, weather W2
    WHERE W1.temp_lo < W2.temp_lo
    AND W1.temp_hi > W2.temp_hi;
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

聚集函式

在一個行集合上計算count(計數)、sum(和)、avg(均值)、max(最大值)和min(最小值)的函式。

--查詢所有記錄中最低溫度中的最高溫度
SELECT max(temp_lo) FROM weather;
--查詢上面的值發生在哪個城市
SELECT city FROM weather
    WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
--獲取每個城市觀測到的最低溫度的最高值
SELECT city, max(temp_lo) FROM weather
    GROUP BY city;
--用HAVING 過濾這些被分組的行
SELECT city, max(temp_lo) FROM weather
    GROUP BY city
    HAVING max(temp_lo) < 40; 
--只給出那些所有temp_lo值都低於40的城市。並且只查詢那些名字以"S"開頭的城市
SELECT city, max(temp_lo) FROM weather
    WHERE city LIKE 'S%'
    GROUP BY city
    HAVING max(temp_lo) < 40; 
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

WHERE和HAVING的基本區別如下:WHERE在分組和聚集計算之前選取輸入行(因此,它控制哪些行進入聚集計算)。因此,WHERE子句不能包含聚集函式; 因為試圖用聚集函式判斷哪些行應輸入給聚集運算是沒有意義的。相反,HAVING子句總是包含聚集函式(嚴格說來,你可以寫不使用聚集的HAVING子句, 但這樣做很少有用。同樣的條件用在WHERE階段會更有效)。

更新

UPDATE weather SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
    WHERE date > '1994-11-28';
  
  • 1
  • 2

刪除

DELETE FROM weather WHERE city = 'Hayward';
DELETE FROM tablename;
  
  • 1
  • 2

如果沒有一個限制,DELETE將從指定表中刪除所有行,把它清空。做這些之前系統不會請求你確認!

檢視

--建立檢視
CREATE VIEW myview AS
    SELECT city, temp_lo, temp_hi, prcp, date, location
        FROM weather, cities
        WHERE city = name;
--檢視檢視
SELECT * FROM myview;
--刪除檢視
DROP VIEW myview
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

外來鍵

為了維持資料的引用完整性

CREATE TABLE cities (
        city     varchar(80) primary key,
        location point
);
CREATE TABLE weather (
        city      varchar(80) references cities(city),
        temp_lo   int,
        temp_hi   int,
        prcp      real,
        date      date
);
--那麼下面是非法的記錄
INSERT INTO weather VALUES ('Berkeley', 45, 53, 0.0, '1994-11-28');
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

事務

事務最重要的一點是它將多個步驟捆綁成了一個單一的、要麼全完成要麼全不完成的操作,一個事務被稱為是原子的。
步驟之間的中間狀態對於其他併發事務是不可見的。
在PostgreSQL中,開啟一個事務需要將SQL命令用BEGIN和COMMIT命令包圍起來。因此我們的銀行事務看起來會是這樣:

BEGIN;
UPDATE weather SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
    WHERE date > '1994-11-28';
COMMIT;
  
  • 1
  • 2
  • 3
  • 4

如果,在事務執行中我們並不想提交,我們可以發出ROLLBACK命令而不是COMMIT命令,這樣所有目前的更新將會被取消。
PostgreSQL實際上將每一個SQL語句都作為一個事務來執行。如果我們沒有發出BEGIN命令,則每個獨立的語句都會被加上一個隱式的BEGIN以及(如果成功)COMMIT來包圍它。一組被BEGIN和COMMIT包圍的語句也被稱為一個事務塊。
也可以利用儲存點來以更細的粒度來控制一個事務中的語句。儲存點允許我們有選擇性地放棄事務的一部分而提交剩下的部分。在使用SAVEPOINT定義一個儲存點後,我們可以在必要時利用ROLLBACK TO回滾到該儲存點。該事務中位於儲存點和回滾點之間的資料庫修改都會被放棄,但是早於該儲存點的修改則會被儲存。
在回滾到儲存點之後,它的定義依然存在,因此我們可以多次回滾到它。反過來,如果確定不再需要回滾到特定的儲存點,它可以被釋放以便系統釋放一些資源。記住不管是釋放儲存點還是回滾到儲存點都會釋放定義在該儲存點之前的所有其他儲存點。
所有這些都發生在一個事務塊內,因此這些對於其他資料庫會話都不可見。當提交整個事務塊時,被提交的動作將作為一個單元變得對其他會話可見,而被回滾的動作則永遠不會變得可見。
現在假設我們從Alice的賬戶扣款100美元,然後存款到Bob的賬戶,結果直到最後才發現我們應該存到Wally的賬戶。我們可以通過使用儲存點來做這件事:

BEGIN;
UPDATE accounts SET balance = balance - 100.00
    WHERE name = 'Alice';
SAVEPOINT my_savepoint;
UPDATE accounts SET balance = balance + 100.00
    WHERE name = 'Bob';
-- oops ... forget that and use Wally's account
ROLLBACK TO my_savepoint;
UPDATE accounts SET balance = balance + 100.00
    WHERE name = 'Wally';
COMMIT;
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

–注:ROLLBACK TO是唯一的途徑來重新控制一個由於錯誤被系統置為中斷狀態的事務塊,而不是完全回滾它並重新啟動

視窗函式

先來一個小例子

SELECT city,temp_lo,avg(temp_lo) OVER(PARTITION BY city) FROM weather
  
  • 1
					<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-7f770a53f2.css" rel="stylesheet">
            </div>

PostgreSQL 基本語法