2.1. SQL语言基础知识
可以在 SQL 命令中自由使用空白(空格/tab/换行符)。
psql 可以识别命令直到分号才结束。
SQL对关键字和标识符大小写不敏感言,只有在标识符用双引号包围时才保留大小写属性。
Postgres SQL 支持标准的 SQL 类型:int, smallint, real, double precision, char(N), varchar(N), date, time, timestamp, interval ,还支持其它的通用类型和丰富的几何类型。
PostgreSQL 允许你自定义任意数量的数据类型。
-- point 类型就是一种 PostgreSQL 特有的数据类型的例子。-- 将保存城市和它们相关的地理位置:CREATE TABLE cities ( name varchar(80), location point);-- point 类型要求一个座标对作为输入,如下:INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
2.2. copy
COPY 在表和文件之间交换数据。
COPY 只能用于表,不能用于视图。当然也可以用于 COPY (SELECT * FROM viewname) TO ...
COPY country TO STDOUT WITH DELIMITER '|';-- 把一个表拷贝到客户端,使用竖直条(|)作为域分隔符:COPY country FROM '/usr1/proj/bray/sql/country_data';-- 从文件中拷贝数据到 country 表中:-- 源文件的文件名必须是后端服务器可访问的,而不是客户端可访问的,因为后端服务器直接读取文件。COPY (SELECT * FROM country WHERE country_name LIKE 'A%') TO '/usr1/proj/bray/sql/a_list_countries.copy';-- 使用一个会被自动删除的临时表,把'A'开头的国家名拷贝到一个文件里.-- SQL语句用()括起来,文件名用''引起来。
语法:
COPY tablename [ ( column [, ...] ) ] FROM { 'filename' | STDIN } [ [ WITH ] [ BINARY ] [ OIDS ] [ DELIMITER [ AS ] 'delimiter' ] [ NULL [ AS ] 'null string' ] [ CSV [ HEADER ] [ QUOTE [ AS ] 'quote' ] [ ESCAPE [ AS ] 'escape' ] [ FORCE NOT NULL column [, ...] ]COPY { tablename [ ( column [, ...] ) ] | ( query ) } TO { 'filename' | STDOUT } [ [ WITH ] [ BINARY ] [ HEADER ] [ OIDS ] [ DELIMITER [ AS ] 'delimiter' ] [ NULL [ AS ] 'null string' ] [ CSV [ HEADER ] [ QUOTE [ AS ] 'quote' ] [ ESCAPE [ AS ] 'escape' ] [ FORCE QUOTE column [, ...] ]
2.3. 查询、聚集
要用到的两张表: I
city | temp_lo | temp_hi | prcp | date |
---|---|---|---|---|
San Francisco | 46 | 50 | 0.25 | 1994-11-27 |
San Francisco | 43 | 57 | 0 | 1994-11-29 |
Hayward | 37 | 54 | 1994-11-29 |
-- 查询气温最高的是哪个城市:SELECT city FROM weather WHERE temp_lo = max(temp_lo); -- 错!因为聚集函数 max 不能用于 WHERE 子句中。存在这个限制是因为 WHERE 子句决定哪些行可以进入聚集阶段;-- 可以用子查询实现这个目的:SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather); city--------------- San Francisco(1 row)
理解聚集和 SQL 的 WHERE 和 HAVING 子句之间的关系非常重要。
WHERE 和 HAVING 的基本区别如下: WHERE 在分组和聚集计算之前选取输入行(它控制哪些行进入聚集计算),而 HAVING 在分组和聚集之后选取输出行。
因此,WHERE 子句不能包含聚集函数;因为试图用聚集函数判断那些行将要输入给聚集运算是没有意义的。相反,HAVING 子句总是包含聚集函数。
当然,你可以写不使用聚集的 HAVING 子句,但这样做没什么好处,因为同样的条件可以更有效地用于 WHERE 阶段。
-- 查询低温中的最高温度(max temp_lo值)低于 40 度、名字以"S"开头的城市-- 可以在 WHERE 里应用城市名称限制,因为它不需要聚集。这样比在 HAVING 里增加限制更加高效,因为我们避免了为那些未通过 WHERE 检查的行进行分组和聚集计算。SELECT city, max(temp_lo) FROM weather WHERE city LIKE 'S%' GROUP BY city HAVING max(temp_lo) < 40;