SQL高级特性

\c study;
/*
begin:视图
对于所作的频繁操作,创建视图比较方便
*/
--创建视图
CREATE VIEW myview AS SELECT city, temp_lo, temp_hi, prcp, date, location FROM weather, cities WHERE city = name;

--使用视图
SELECT * FROM myview;

/*
next:外键
假如你想weather中name必须是cities出现的city,不想weather中name数据不被意外的插入或删除,那么使用是个较好的选择
*/
--重新设计cities weather表格
CREATE TABLE cities(
    city            varchar(80)  primary key,
    location        point
);

CREATE TABLE weather (
    name            varchar(80)  references cities(city),
    temp_lo         int,
    temp_hi         int,
    prcp            real,
    date            date
);

--插入非法记录会报错

INSERT INTO weather(name,temp_lo,temp_hi,prcp,date)
 VALUES ('Berkeley',45,53,0.0,'1994-11-28');


/*
next:事务
*/
/*
before:创建使用的表插入使用的数据
*/
CREATE  TABLE account (
    name        varchar(30),
    blance      real
);

INSERT INTO account(name,blance) VALUES ('Alice',1200.14);
INSERT INTO account(name,blance) VALUES ('Bob',300);
INSERT INTO account(name,blance) VALUES ('Wally',4000);
/*
operation:Alice给Bob转$100,后系统检测到错误,应该是
Wally转$100给Bob
*/
UPDATE account SET blance = blance - 100 WHERE name = 'Alice';
--我们更新完Alice账户时,其他会话就已经知道Alice的账户减少了100,而Bob的$100还未增加,我们可能还要检查验证Alice身份,发现不对又要减少Alice的blance,但其他会话可能已经使用了Alice错误操作的结果
UPDATE account SET blance = blance + 100 WHERE 
name = 'BOb';
/*
problem:如果两个操作其中一个操作失败了,而我们不得而知,那么对于金融系统之类的业务就会有很大的危害性,而且这也是我们不希望看到的
slove:数据库事务的概念很容易帮我们解决这个问题
事务容许我们在任何的操作点撤销和提交我们的操作
*/
BEGIN;
UPDATE account SET blance = blance - 100.00 WHERE name = 'Alice';
SAVEPOINT my_savepoint;
/*发现Alice身份不对,我们应该使用Wally,因为我们使用的是一个事务会话,事务还未结束,Alice的操作多余其他会话是不可见的,所以我们保证了数据的安全性,再用ROLLBACK TO可以很轻松的撤销我们错误的操作*/
ROLLBACK TO my_savepoint;
UPDATE account SET blance = blance - 100.00 WHERE 
name = 'Wally';
SAVEPOINT my_secondpoint; --保持一次操作一次SAVEPOINT的好习惯,除非你真的保证不会ROLLBACK TO
UPDATE account SET blance = blance + 100.00 WHERE 
name = 'Bob';
COMMIT;

/*
next:窗口函数
*/
/*
before:创建所需要的表和数据
*/
CREATE TABLE empsalary (
    depname         varchar(30), --部门名
    empno           int,         --员工编号
    salary          real         --员工工资
);
--插入数据
INSERT INTO empsalary(depname,empno,salary) VALUES
('develop',11,5200.0);
INSERT INTO empsalary(depname,empno,salary) VALUES
('develop',32,4200.0);
INSERT INTO empsalary(depname,empno,salary) VALUES ('develop',54,6700.0);
INSERT INTO empsalary(depname,empno,salary) VALUES ('personel',16,9770);
INSERT INTO empsalary(depname,empno,salary) VALUES ('personel',10,5432);
/*
operation:计算部门名相同员工的平均工资
*/
--slove1和slove2的思想是找到我们想要的数据建视图或临时表并结合原有数据进行检索
--slove1:
CREATE VIEW avg_view AS SELECT avg(salary) AS avg_salary, depname AS view_depname FROM empsalary GROUP BY depname;
SELECT depname,empno,salary,avg_salary FROM empsalary,avg_view where avg_view.view_depname = empsalary.depname;
--slove2:
SELECT depname,empno,salary,avg_salary FROM empsalary,(SELECT avg(salary) AS avg_salary,depname AS table_depname FROM empsalary GROUP BY depname) AS avg_table where avg_table.table_depname = depname;

--slove3:使用窗口函数
--首先划分窗口,然后根据窗口检索
--窗口大小:depname相同的为一个窗口
SELECT depname,empno,salary, avg(salary) OVER(PARTITION BY depname) FROM empsalary;

--窗口函数内还可以使用ORDER BY来控制行的顺序
--窗口大小:相同depname且通过salay排序到当前行为当前窗口
SELECT depname,empno,salary, rank() OVER(PARTITION BY depname ORDER BY salary) FROM empsalary;

--窗口大小:所有行
SELECT salary,sum(salary) OVER() FROM empsalary;

SELECT salary,sum(salary) OVER(order by salary) FROM empsalary;

SELECT depname, empno, salary FROM (SELECT depname , empno,salary,rank() OVER(PARTITION BY depname ORDER BY salary DESC,empno) AS pos FROM empsalary)
AS ss WHERE pos < 3;

--定义窗口,方便不同的行为进行引用
SELECT salary,sum(salary) OVER w, avg(salary) OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);

--继承
/*
之前我们已经创建了一个表cities意在包含所有城市,而我们接下来创建了一个表capitals意在包含所有首部城市,首部城市会包含城市的信息
*/
--solve1
CREATE TABLE capitals (
    name               text,
    population         real,
    altitude           int,     --海拔高度(单位英尺)
    state              char(2)
);

CREATE TABLE non_capitals (
    name                text,
    population          real,
    altitude            int
);
--把城市划分为包含非首部城市和首部城市的视图
--也算的上是一奇技淫巧了
CREATE VIEW cities AS SELECT name,population,altitude  FROM capitals UNION SELECT name, population, altitude FROM non_capitals;

--使用继承使captals包含cities所有字段

CREATE TABLE cities (
    name          text,
    population    real,
    altitude      int
);

CREATE TABLE capitals (
    state        char(2)
) INHERITS(cities);
--插入数据看看效果

INSERT INTO cities(name,population,altitude)
VALUES('安庆市',1500.01,2220);

INSERT INTO cities(name,population,altitude)
VALUES('六安市',1000.33,500);

INSERT INTO cities(name,population,altitude)
VALUES('芜湖市',1300.55,667);

INSERT INTO capitals(name,population,altitude,state) VALUES('南昌市',1400,3400,'IN');

INSERT INTO capitals(name,population,altitude,state) VALUES('安庆市',1500.01,2200,'IS');

--对capital表查询

SELECT name,altitude FROM capitals WHERE altitude > 1500;
--对cities表进行查询 不加ONLY会对cities的继承体系所有子表进行查询
SELECT name,altitude FROM ONLY cities WHERE altitude > 1500;

/*
end
*/












猜你喜欢

转载自blog.csdn.net/rgbmarco/article/details/80602889