1. 引言
PostgreSQL 作为功能强大的开源关系型数据库,不仅支持标准 SQL,还通过 PostGIS 扩展提供了丰富的地理空间数据处理能力。本文整理 PostgreSQL 日常开发中高频使用的 SQL 语句,并重点介绍与 GIS 相关的常用函数,帮助读者快速查阅和应用。
2. 常用 SQL 语句
2.1 数据库与表操作
创建数据库、创建表、修改表结构是日常开发的基础操作。
sql
-- 创建数据库
CREATE DATABASE mydb;
-- 创建表
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE,
created_at TIMESTAMP DEFAULT NOW()
);
-- 添加字段
ALTER TABLE users ADD COLUMN age INT;
-- 删除字段
ALTER TABLE users DROP COLUMN age;
-- 修改字段类型
ALTER TABLE users ALTER COLUMN name TYPE VARCHAR(200);
-- 删除表
DROP TABLE IF EXISTS users;
2.2 数据查询
SELECT 查询是使用频率最高的语句,支持条件过滤、排序、分页、聚合等操作。
sql
-- 基础查询
SELECT id, name, email FROM users WHERE age > 18 ORDER BY created_at DESC;
-- 分页查询
SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 20;
-- 聚合查询
SELECT COUNT(*) AS total, AVG(age) AS avg_age FROM users;
-- 分组统计
SELECT department, COUNT(*) AS cnt FROM employees GROUP BY department HAVING COUNT(*) > 5;
-- 模糊查询
SELECT * FROM users WHERE name LIKE '张%';
-- 去重查询
SELECT DISTINCT department FROM employees;
2.3 数据操作
插入、更新、删除数据是日常维护的常用操作。
sql
-- 插入数据
INSERT INTO users (name, email) VALUES ('张三', 'zhangsan@example.com');
-- 批量插入
INSERT INTO users (name, email) VALUES
('李四', 'lisi@example.com'),
('王五', 'wangwu@example.com');
-- 更新数据
UPDATE users SET age = 30 WHERE name = '张三';
-- 删除数据
DELETE FROM users WHERE id = 10;
-- 清空表
TRUNCATE TABLE users;
2.4 索引与性能优化
合理使用索引可以显著提升查询性能。
sql
-- 创建普通索引
CREATE INDEX idx_users_name ON users (name);
-- 创建唯一索引
CREATE UNIQUE INDEX idx_users_email ON users (email);
-- 创建组合索引
CREATE INDEX idx_users_dept_age ON employees (department, age);
-- 删除索引
DROP INDEX idx_users_name;
-- 查看执行计划
EXPLAIN ANALYZE SELECT * FROM users WHERE name = '张三';
2.5 常用函数
PostgreSQL 内置了大量字符串、日期、数值处理函数。
sql
-- 字符串函数
SELECT UPPER('hello'), LOWER('HELLO'), LENGTH('hello'), CONCAT('a', 'b');
-- 日期函数
SELECT NOW(), CURRENT_DATE, CURRENT_TIME;
SELECT DATE_TRUNC('month', NOW());
SELECT NOW() - INTERVAL '7 days';
-- 数值函数
SELECT ROUND(3.14159, 2), CEIL(3.2), FLOOR(3.8), ABS(-5);
-- 条件函数
SELECT CASE WHEN age >= 18 THEN '成年' ELSE '未成年' END FROM users;
SELECT COALESCE(NULL, '默认值');
SELECT NULLIF(0, 0);
3. GIS 相关函数
3.1 PostGIS 扩展安装
PostGIS 是 PostgreSQL 的地理空间扩展,使用前需要先安装启用。
sql
-- 创建 PostGIS 扩展
CREATE EXTENSION IF NOT EXISTS postgis;
-- 查看版本
SELECT PostGIS_Version();
3.2 几何类型与构造函数
PostGIS 支持点、线、面等几何类型,并提供多种构造函数。
sql
-- 创建带空间字段的表
CREATE TABLE places (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
geom GEOMETRY(Point, 4326)
);
-- 从坐标构造点
SELECT ST_GeomFromText('POINT(116.4074 39.9042)', 4326);
SELECT ST_MakePoint(116.4074, 39.9042);
-- 构造线
SELECT ST_GeomFromText('LINESTRING(0 0, 1 1, 2 2)', 4326);
-- 构造面
SELECT ST_GeomFromText('POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))', 4326);
-- 插入空间数据
INSERT INTO places (name, geom) VALUES ('天安门', ST_GeomFromText('POINT(116.3975 39.9087)', 4326));
3.3 空间关系判断函数
空间关系函数用于判断几何对象之间的位置关系。
sql
-- 判断是否相交
SELECT ST_Intersects(geom1, geom2);
-- 判断是否包含
SELECT ST_Contains(polygon_geom, point_geom);
-- 判断是否相邻
SELECT ST_Touches(geom1, geom2);
-- 判断是否重叠
SELECT ST_Overlaps(geom1, geom2);
-- 判断是否在内部
SELECT ST_Within(point_geom, polygon_geom);
-- 判断是否相等
SELECT ST_Equals(geom1, geom2);
-- 判断距离是否在指定范围内
SELECT ST_DWithin(geom1, geom2, 1000);
3.4 空间计算函数
空间计算函数用于计算距离、面积、长度等度量值。
sql
-- 计算两点间距离(度)
SELECT ST_Distance(
ST_GeomFromText('POINT(116.4074 39.9042)', 4326),
ST_GeomFromText('POINT(121.4737 31.2304)', 4326)
);
-- 计算球面距离(米)
SELECT ST_DistanceSphere(
ST_GeomFromText('POINT(116.4074 39.9042)', 4326),
ST_GeomFromText('POINT(121.4737 31.2304)', 4326)
);
-- 计算面积
SELECT ST_Area(geom) FROM places;
-- 计算长度
SELECT ST_Length(geom) FROM roads;
-- 计算几何中心点
SELECT ST_Centroid(geom) FROM places;
-- 计算最小外接矩形
SELECT ST_Envelope(geom) FROM places;
3.5 空间分析函数
空间分析函数用于缓冲区、合并、裁剪等高级分析操作。
sql
-- 创建缓冲区
SELECT ST_Buffer(geom, 0.01) FROM places WHERE name = '天安门';
-- 合并几何对象
SELECT ST_Union(geom) FROM places;
-- 求交集
SELECT ST_Intersection(geom1, geom2);
-- 求差集
SELECT ST_Difference(geom1, geom2);
-- 简化几何
SELECT ST_Simplify(geom, 0.001) FROM roads;
-- 转换坐标系
SELECT ST_Transform(geom, 3857) FROM places;
3.6 空间查询实战示例
结合空间函数进行实际业务查询。
sql
-- 查询指定点 1 公里范围内的地点
SELECT name FROM places
WHERE ST_DWithin(
geom,
ST_GeomFromText('POINT(116.4074 39.9042)', 4326),
0.01
);
-- 按距离排序查询最近的地点
SELECT name, ST_DistanceSphere(geom, ST_GeomFromText('POINT(116.4074 39.9042)', 4326)) AS distance
FROM places
ORDER BY distance
LIMIT 10;
-- 查询落在指定区域内的地点
SELECT name FROM places
WHERE ST_Within(
geom,
ST_GeomFromText('POLYGON((116.3 39.8, 116.5 39.8, 116.5 40.0, 116.3 40.0, 116.3 39.8))', 4326)
);
-- 空间索引加速查询
CREATE INDEX idx_places_geom ON places USING GIST (geom);
4. 总结
PostgreSQL 提供了完善的 SQL 语法和丰富的内置函数,配合 PostGIS 扩展可以高效处理地理空间数据。日常开发中,掌握基础 SQL 语句是必备技能,而 GIS 相关函数则能帮助解决位置查询、距离计算、空间分析等复杂业务需求。建议在实际项目中结合空间索引优化查询性能,并根据业务场景选择合适的坐标系。