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;