SQL基础语法 #
一、SQL概述 #
1.1 TimescaleDB SQL特点 #
text
TimescaleDB SQL特点:
完全兼容PostgreSQL
├── 标准SQL语法
├── 所有数据类型
├── 所有操作符
├── 所有函数
└── 所有索引类型
时序扩展
├── 超表函数
├── 时间桶函数
├── 超函数
├── 连续聚合
└── 时序特定操作
1.2 SQL分类 #
text
SQL语句分类:
DDL(数据定义语言)
├── CREATE - 创建对象
├── ALTER - 修改对象
├── DROP - 删除对象
└── TRUNCATE - 清空表
DML(数据操作语言)
├── INSERT - 插入数据
├── UPDATE - 更新数据
├── DELETE - 删除数据
└── SELECT - 查询数据
DCL(数据控制语言)
├── GRANT - 授予权限
└── REVOKE - 撤销权限
TCL(事务控制语言)
├── BEGIN - 开始事务
├── COMMIT - 提交事务
├── ROLLBACK - 回滚事务
└── SAVEPOINT - 保存点
二、基本语法规则 #
2.1 注释 #
sql
-- 单行注释
/*
* 多行注释
* 可以跨越多行
*/
-- SQL语句不区分大小写(关键字)
SELECT * FROM users; -- 推荐
select * from users; -- 也可以
-- 但标识符区分大小写(如果用双引号)
SELECT * FROM "Users"; -- 表名必须完全匹配大小写
2.2 标识符命名 #
sql
-- 合法的标识符
CREATE TABLE sensor_data (
time TIMESTAMPTZ,
sensor_id INTEGER,
temperature DOUBLE PRECISION
);
-- 使用双引号可以包含特殊字符
CREATE TABLE "sensor-data" (
"time-stamp" TIMESTAMPTZ,
"sensor-id" INTEGER
);
-- 命名规范建议
-- 1. 使用小写字母
-- 2. 使用下划线分隔单词
-- 3. 避免使用保留字
-- 4. 见名知意
2.3 数据类型 #
sql
-- 数值类型
INTEGER -- 整数
BIGINT -- 大整数
SMALLINT -- 小整数
DECIMAL(p,s) -- 精确小数
NUMERIC(p,s) -- 精确小数
REAL -- 单精度浮点
DOUBLE PRECISION -- 双精度浮点
-- 字符串类型
CHAR(n) -- 定长字符串
VARCHAR(n) -- 变长字符串
TEXT -- 无限长字符串
-- 时间类型
DATE -- 日期
TIME -- 时间
TIMESTAMP -- 时间戳(无时区)
TIMESTAMPTZ -- 时间戳(带时区)- TimescaleDB推荐
INTERVAL -- 时间间隔
-- 布尔类型
BOOLEAN -- true/false
-- 其他类型
JSON -- JSON数据
JSONB -- 二进制JSON
UUID -- UUID
ARRAY -- 数组
三、数据库操作 #
3.1 创建数据库 #
sql
-- 创建数据库
CREATE DATABASE tsdb;
-- 带参数创建
CREATE DATABASE tsdb
WITH
OWNER = postgres
ENCODING = 'UTF8'
LC_COLLATE = 'en_US.UTF-8'
LC_CTYPE = 'en_US.UTF-8'
TEMPLATE = template0;
-- 连接数据库
\c tsdb
-- 删除数据库
DROP DATABASE IF EXISTS tsdb;
3.2 创建扩展 #
sql
-- 创建TimescaleDB扩展
CREATE EXTENSION IF NOT EXISTS timescaledb;
-- 查看已安装扩展
\dx
-- 查看扩展详情
\dx+ timescaledb
四、表操作 #
4.1 创建普通表 #
sql
-- 创建传感器数据表
CREATE TABLE sensor_data (
time TIMESTAMPTZ NOT NULL,
sensor_id INTEGER NOT NULL,
temperature DOUBLE PRECISION,
humidity DOUBLE PRECISION,
pressure DOUBLE PRECISION,
location VARCHAR(100)
);
-- 添加主键
ALTER TABLE sensor_data
ADD PRIMARY KEY (time, sensor_id);
-- 添加索引
CREATE INDEX idx_sensor_id ON sensor_data (sensor_id);
CREATE INDEX idx_time ON sensor_data (time DESC);
4.2 创建超表 #
sql
-- 将普通表转换为超表
SELECT create_hypertable(
'sensor_data', -- 表名
'time', -- 时间列
if_not_exists => TRUE
);
-- 带空间分区的超表
SELECT create_hypertable(
'sensor_data',
'time',
partitioning_column => 'sensor_id',
number_partitions => 4
);
-- 查看超表信息
SELECT * FROM timescaledb_information.hypertables;
4.3 修改表 #
sql
-- 添加列
ALTER TABLE sensor_data
ADD COLUMN battery_level DOUBLE PRECISION;
-- 修改列类型
ALTER TABLE sensor_data
ALTER COLUMN location TYPE TEXT;
-- 添加约束
ALTER TABLE sensor_data
ADD CONSTRAINT chk_temperature
CHECK (temperature BETWEEN -50 AND 100);
-- 删除列
ALTER TABLE sensor_data
DROP COLUMN IF EXISTS battery_level;
4.4 删除表 #
sql
-- 删除表
DROP TABLE IF EXISTS sensor_data;
-- 级联删除(删除依赖对象)
DROP TABLE IF EXISTS sensor_data CASCADE;
五、数据插入 #
5.1 基本插入 #
sql
-- 插入单行数据
INSERT INTO sensor_data (time, sensor_id, temperature, humidity)
VALUES (NOW(), 1, 25.5, 60.0);
-- 插入多行数据
INSERT INTO sensor_data (time, sensor_id, temperature, humidity) VALUES
(NOW() - INTERVAL '1 hour', 1, 24.8, 58.5),
(NOW() - INTERVAL '2 hours', 1, 24.5, 57.2),
(NOW() - INTERVAL '3 hours', 2, 26.1, 61.0);
-- 插入所有列
INSERT INTO sensor_data VALUES
(NOW(), 3, 23.9, 59.5, 1013.25, 'Beijing');
5.2 从查询插入 #
sql
-- 从其他表插入
INSERT INTO sensor_data_archive
SELECT * FROM sensor_data
WHERE time < NOW() - INTERVAL '30 days';
-- 带条件插入
INSERT INTO high_temp_sensors (time, sensor_id, temperature)
SELECT time, sensor_id, temperature
FROM sensor_data
WHERE temperature > 30;
5.3 批量导入 #
sql
-- 使用COPY命令导入CSV
COPY sensor_data (time, sensor_id, temperature, humidity)
FROM '/path/to/data.csv'
WITH (FORMAT csv, HEADER true);
-- 导出数据
COPY (
SELECT * FROM sensor_data
WHERE time > NOW() - INTERVAL '7 days'
) TO '/path/to/export.csv'
WITH (FORMAT csv, HEADER true);
六、数据查询 #
6.1 基本查询 #
sql
-- 查询所有数据
SELECT * FROM sensor_data;
-- 查询特定列
SELECT time, sensor_id, temperature
FROM sensor_data;
-- 条件查询
SELECT * FROM sensor_data
WHERE sensor_id = 1
ORDER BY time DESC;
-- 限制结果数量
SELECT * FROM sensor_data
ORDER BY time DESC
LIMIT 100;
6.2 时间范围查询 #
sql
-- 查询最近一小时数据
SELECT * FROM sensor_data
WHERE time > NOW() - INTERVAL '1 hour';
-- 查询特定时间范围
SELECT * FROM sensor_data
WHERE time BETWEEN '2024-01-01' AND '2024-01-31';
-- 查询今天的数据
SELECT * FROM sensor_data
WHERE time >= CURRENT_DATE;
-- 查询昨天的数据
SELECT * FROM sensor_data
WHERE time >= CURRENT_DATE - INTERVAL '1 day'
AND time < CURRENT_DATE;
6.3 聚合查询 #
sql
-- 基本聚合
SELECT
sensor_id,
COUNT(*) as reading_count,
AVG(temperature) as avg_temp,
MAX(temperature) as max_temp,
MIN(temperature) as min_temp
FROM sensor_data
WHERE time > NOW() - INTERVAL '24 hours'
GROUP BY sensor_id;
-- 使用时间桶分组
SELECT
time_bucket('1 hour', time) AS bucket,
sensor_id,
AVG(temperature) as avg_temp
FROM sensor_data
WHERE time > NOW() - INTERVAL '24 hours'
GROUP BY bucket, sensor_id
ORDER BY bucket DESC;
6.4 连接查询 #
sql
-- 创建传感器信息表
CREATE TABLE sensors (
sensor_id INTEGER PRIMARY KEY,
name VARCHAR(100),
location VARCHAR(100),
type VARCHAR(50)
);
-- 连接查询
SELECT
s.name,
s.location,
sd.time,
sd.temperature
FROM sensor_data sd
JOIN sensors s ON sd.sensor_id = s.sensor_id
WHERE sd.time > NOW() - INTERVAL '1 hour';
七、数据更新 #
7.1 基本更新 #
sql
-- 更新单个字段
UPDATE sensor_data
SET temperature = 25.6
WHERE time = '2024-01-01 10:00:00'
AND sensor_id = 1;
-- 更新多个字段
UPDATE sensor_data
SET
temperature = 25.6,
humidity = 61.0
WHERE sensor_id = 1
AND time > NOW() - INTERVAL '1 hour';
-- 条件更新
UPDATE sensor_data
SET temperature = temperature * 1.1
WHERE temperature < 20;
7.2 使用子查询更新 #
sql
-- 基于其他表更新
UPDATE sensor_data sd
SET location = s.location
FROM sensors s
WHERE sd.sensor_id = s.sensor_id;
八、数据删除 #
8.1 基本删除 #
sql
-- 删除特定数据
DELETE FROM sensor_data
WHERE time < NOW() - INTERVAL '90 days';
-- 条件删除
DELETE FROM sensor_data
WHERE sensor_id = 1
AND temperature IS NULL;
-- 删除所有数据(保留表结构)
TRUNCATE TABLE sensor_data;
8.2 使用保留策略 #
sql
-- 添加保留策略(自动删除旧数据)
SELECT add_retention_policy('sensor_data', INTERVAL '90 days');
-- 查看保留策略
SELECT * FROM timescaledb_information.jobs
WHERE proc_name = 'policy_retention';
-- 删除保留策略
SELECT remove_retention_policy('sensor_data');
九、事务处理 #
9.1 基本事务 #
sql
-- 开始事务
BEGIN;
-- 执行操作
INSERT INTO sensor_data VALUES
(NOW(), 1, 25.5, 60.0);
UPDATE sensors SET last_reading = NOW()
WHERE sensor_id = 1;
-- 提交事务
COMMIT;
-- 或者回滚
ROLLBACK;
9.2 保存点 #
sql
BEGIN;
INSERT INTO sensor_data VALUES
(NOW(), 1, 25.5, 60.0);
-- 创建保存点
SAVEPOINT sp1;
INSERT INTO sensor_data VALUES
(NOW(), 2, 26.0, 61.0);
-- 回滚到保存点
ROLLBACK TO SAVEPOINT sp1;
-- 提交事务
COMMIT;
十、常用函数 #
10.1 时间函数 #
sql
-- 当前时间
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_DATE;
SELECT CURRENT_TIME;
-- 时间计算
SELECT NOW() - INTERVAL '1 day';
SELECT NOW() + INTERVAL '1 hour';
SELECT time_bucket('1 hour', NOW());
-- 时间提取
SELECT EXTRACT(YEAR FROM NOW());
SELECT EXTRACT(MONTH FROM NOW());
SELECT EXTRACT(DAY FROM NOW());
SELECT EXTRACT(HOUR FROM NOW());
-- 时间格式化
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD HH24:MI:SS');
10.2 聚合函数 #
sql
-- 基本聚合
SELECT COUNT(*) FROM sensor_data;
SELECT SUM(temperature) FROM sensor_data;
SELECT AVG(temperature) FROM sensor_data;
SELECT MAX(temperature) FROM sensor_data;
SELECT MIN(temperature) FROM sensor_data;
-- 统计函数
SELECT STDDEV(temperature) FROM sensor_data;
SELECT VARIANCE(temperature) FROM sensor_data;
-- 分位数
SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY temperature)
FROM sensor_data;
10.3 字符串函数 #
sql
-- 字符串连接
SELECT 'Temperature: ' || temperature || '°C'
FROM sensor_data;
-- 字符串处理
SELECT UPPER(location) FROM sensor_data;
SELECT LOWER(location) FROM sensor_data;
SELECT SUBSTRING(location, 1, 10) FROM sensor_data;
-- 字符串查找
SELECT * FROM sensor_data
WHERE location LIKE '%Beijing%';
十一、索引 #
11.1 创建索引 #
sql
-- 创建B-tree索引
CREATE INDEX idx_sensor_id ON sensor_data (sensor_id);
-- 创建时间索引
CREATE INDEX idx_time ON sensor_data (time DESC);
-- 创建复合索引
CREATE INDEX idx_sensor_time ON sensor_data (sensor_id, time DESC);
-- 创建唯一索引
CREATE UNIQUE INDEX idx_unique_reading
ON sensor_data (time, sensor_id);
11.2 索引管理 #
sql
-- 查看索引
\di
-- 删除索引
DROP INDEX IF EXISTS idx_sensor_id;
-- 重建索引
REINDEX INDEX idx_sensor_id;
-- 并发创建索引(不锁表)
CREATE INDEX CONCURRENTLY idx_sensor_location
ON sensor_data (location);
十二、总结 #
SQL语法要点:
| 类别 | 关键字 | 用途 |
|---|---|---|
| DDL | CREATE/ALTER/DROP | 定义数据库对象 |
| DML | INSERT/UPDATE/DELETE/SELECT | 操作数据 |
| DCL | GRANT/REVOKE | 控制权限 |
| TCL | BEGIN/COMMIT/ROLLBACK | 控制事务 |
TimescaleDB扩展:
- 超表函数:create_hypertable等
- 时间函数:time_bucket等
- 保留策略:add_retention_policy等
- 超函数:时序分析函数
下一步,让我们学习数据类型!
最后更新:2026-03-27