PostgreSQL学习笔记(二)—— 概览

数据库

  • 创建数据库: createdb dbname

  • 指定用户名创建数据库: createdb -U username dbname

  • 删除数据库: dropdb dbname

  • 访问数据库: psql [-U username] dbname

  • 交互式环境下数据库内执行select version();会进入到一个新页面,要返回按q

  • 退出数据库: \qexitquit

  • 创建表: CREATE TABLE weather (city varchar(80), temp_low int, temp_high int, date date);

  • 查看表结构: \d tablename;

  • 创建表时--表示注释,--到行尾的东西都会被忽略

  • 删除表: drop table tablename;

  • 表中增加行: insert into weather values('San Francisco', 46, 50, 0.25, '1994-11-27');

  • COPY命令可以一次性向表中装填大量数据: COPY weather FROM '/home/user/weather.txt';

  • 查询表: select city, (temp_lo+temp_hi)/2, date from weather;

  • 查询结果消除重复行: SELECT DISTINCT city FROM weather;

  • 指定表的列查询: select weather.city, cities.location from weather, cities where cities.name = weather.city;

  • 设置别名: select * from weather w, cities c where w.city = c.name;

  • 聚集函数:

    • 最大值: 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;

    • like: select city, max(temp_lo) from weather where city like 's%' group by city having max(temp_lo) < 40;

    • where 和 having: WHERE在分组和聚集计算之前选取输入行(因此,它控制哪些行进入聚集计算), 而HAVING在分组和聚集之后选取分组行。因此,WHERE子句不能包含聚集函数;因为试图用聚集函数判断哪些行应输入给聚集运算是没有意义的。相反,HAVING子句总是包含聚集函数(严格说来,你可以写不使用聚集的HAVING子句, 但这样做很少有用。同样的条件用在WHERE阶段会更有效)

  • 更新行: update weather set temp_hi = temp_hi - 2 where date > '1994-11-28';

  • 删除行: delete from weather where city = 'Hayward';

    • 注: delete from tablename;会直接删除表中所有行而删除之前系统不会请求确认
  • 增加主键: alter table weather add primary key (city);

  • 增加外键: alter table weather add constraint foreignkeyName foreign key (city) references cities(name);

高级特性

  • 视图:

    • create view myview as select city, temo_lo, date, location from weather, cities where city = name;

    • select * from myview;

  • 事务

    • 开启一个事务需要将SQL命令用BEGINCOMMIT命令包围起来,如下:

    • 在事务中如果并不想提交,可以发出ROLLBACK命令而不是COMMIT,这样所有目前的更新将被取消

BEGIN;
UPDATE accounts SET balance = balance - 100.00
    WHERE name = 'Alice';
-- etc etc
COMMIT;
  • 保存点
    • 在使用SAVEPOINT定义一个保存点后,我们可以在必要时利用ROLLBACK TO回滚到该保存点。该事务中位于保存点和回滚点之间的数据库修改都会被放弃,但是早于该保存点的修改则会被保存

    • 在回滚到保存点之后,它的定义依然存在,因此我们可以多次回滚到它。如果确定不再需要回滚到特定的保存点,它可以被释放以便系统释放一些资源。记住不管是释放保存点还是回滚到保存点都会释放定义在该保存点之后的所有其他保存点

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;
  • 窗口函数

    • 一个窗口函数调用总是包含一个直接跟在窗口函数名及其参数之后的OVER子句。这使得它从句法上和一个普通函数或非窗口函数区分开来。OVER子句决定究竟查询中的哪些行被分离出来由窗口函数处理。
    • OVER子句中的PARTITION BY子句指定了将具有相同PARTITION BY表达式值的行分到组或者分区
    • eg: SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary DESC) FROM empsalary;
    • 窗口函数只允许出现在查询的SELECT列表和ORDER BY子句中。它们不允许出现在其他地方,例如GROUP BYHAVINGWHERE子句中。这是因为窗口函数的执行逻辑是在处理完这些子句之后
-- 展示如何将每一个员工的薪水与他/她所在部门的平均薪水进行比较
SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;

/*  depname  | empno | salary |          avg
-----------+-------+--------+-----------------------
 develop   |    11 |   5200 | 5020.0000000000000000
 develop   |     7 |   4200 | 5020.0000000000000000
 develop   |     9 |   4500 | 5020.0000000000000000
 develop   |     8 |   6000 | 5020.0000000000000000
 develop   |    10 |   5200 | 5020.0000000000000000
 personnel |     5 |   3500 | 3700.0000000000000000
 personnel |     2 |   3900 | 3700.0000000000000000
 sales     |     3 |   4800 | 4866.6666666666666667
 sales     |     1 |   5000 | 4866.6666666666666667
 sales     |     4 |   4800 | 4866.6666666666666667
 */
 --最开始的三个输出列直接来自于表empsalary,并且表中每一行都有一个输出行。第四列表示对与当前行具有相同depname值的所有表行取得平均值(这实际和非窗口avg聚集函数是相同的函数,但是OVER子句使得它被当做一个窗口函数处理并在一个合适的窗口帧上计算。)
  • 继承
--创建两个表:cities、capitals。自然地,首都也是城市,所以我们需要有某种方式能够在列举所有城市的时候也隐式地包含首都。
CREATE TABLE cities (
    name        text,
    population  real,
    altitude    int     -- (in ft)
);

CREATE TABLE capitals (
    state       char(2)
) INHERITS (cities);
--在这种情况下,一个capitals的行从它的父亲cities继承了所有列(name、population和altitude)
-- 查找所有海拔高于500尺且不是州首府的城市
SELECT name, altitude 
    FROM ONLY cities
    WHERE altitude > 500;
-- ONLY用于指示查询只在cities表上进行而不会涉及到继承层次中位于cities之下的其他表。很多我们已经讨论过的命令 — SELECT、UPDATE 和DELETE — 都支持这个ONLY记号
-- 尽管继承很有用,但是它还未与唯一约束或外键集成,这也限制了它的可用性

posted on 2019-07-27 15:44  GaiheiluKamei  阅读(203)  评论(0编辑  收藏  举报

导航