经典SQL语句整理了库表、索引、连接、分页、去重等常用写法。下面按原文条目保留全部语句,方便查阅。语法偏 SQL Server / DB2,MySQL 有对应写法时请自行替换。
一、基础:库、表、索引、视图
1. 创建 / 删除数据库
CREATE DATABASE database-name
DROP DATABASE dbname
2. 备份 SQL Server
USE master
EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'
BACKUP DATABASE pubs TO testBack
3. 建表、按旧表建新表、删表
create table tabname(col1 type1 [not null] [primary key], col2 type2 [not null], ..)
根据已有表创建新表:
A:create table tab_new like tab_old
B:create table tab_new as select col1,col2… from tab_old definition only
drop table tabname
4. 加列、主键、索引、视图
Alter table tabname add column col type
列增加后将不能删除。DB2 中列加上后数据类型也不能改变,唯一能改的是增加 varchar 类型的长度。
Alter table tabname add primary key(col)
Alter table tabname drop primary key(col)
create [unique] index idxname on tabname(col….)
drop index idxname
create view viewname as select statement
drop view viewname
索引不可更改,想改必须删除重建。
5. 基本增删改查与聚合
select * from table1 where 范围
insert into table1(field1,field2) values(value1,value2)
delete from table1 where 范围
update table1 set field1=value1 where 范围
select * from table1 where field1 like '%value1%'
select * from table1 order by field1,field2 [desc]
select count(*) as totalcount from table1
select sum(field1) as sumvalue from table1
select avg(field1) as avgvalue from table1
select max(field1) as maxvalue from table1
select min(field1) as minvalue from table1
二、集合运算与外连接
UNION 组合两个结果表并消去重复行;UNION ALL 不消除。 EXCEPT 留下在 TABLE1 但不在 TABLE2 的行;EXCEPT ALL 保留重复。 INTERSECT 只留两边都有的行;INTERSECT ALL 不消重。参与运算的结果行列必须一致。
left (outer) join:结果包括匹配行,也包括左表所有行。
select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUTER JOIN b ON a.a = b.c
right (outer) join:包括匹配行和右表所有行。 full/cross (outer) join:还包括两个表中的所有记录。
Group by:分组后只能得到组相关信息(count、sum、max、min、avg)。SQL Server 不能以 text、ntext、image 作为分组依据;select 里统计函数字段不能和普通字段随意放在一起。
分离 / 附加 / 改名
sp_detach_db
sp_attach_db -- 后接库名,附加需要完整路径名
sp_renamedb 'old_name', 'new_name'
| 运算 |
结果 |
| UNION |
两表行合并,去重 |
| UNION ALL |
合并,不去重 |
| EXCEPT |
在 A 不在 B |
| INTERSECT |
A 与 B 都有 |
| LEFT/RIGHT/FULL JOIN |
保留左 / 右 / 两侧未匹配行 |
三、提升:复制、子查询、分页
1. 只复制结构(源 a 新表 b)
select * into b from a where 1<>1 -- 仅 SQL Server
select top 0 * into b from a
2. 拷贝数据
insert into b(a, b, c) select d,e,f from b;
3. 跨库拷贝(Access 可用)
insert into b(a, b, c) select d,e,f from b in '具体数据库' where 条件
例子:..from b in ‘”&Server.MapPath(“.”)&”\data.mdb” &’ where..
4. 子查询
select a,b,c from a where a IN (select d from b )
select a,b,c from a where a IN (1,2,3)
5. 显示文章、提交人和最后回复时间
select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b
6. 外连接 / 在线视图 / between / in
select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUTER JOIN b ON a.a = b.c
select * from (SELECT a,b,c FROM a) T where t.a > 1;
select * from table1 where time between time1 and time2
select a,b,c from table1 where a not between 数值1 and 数值2
select * from table1 where a [not] in ('值1','值2','值4','值6')
between 限制范围时包括边界值,not between 不包括。
7. 删除主表中副表已没有的信息
delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )
8. 四表联查
select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....
9. 日程安排提前五分钟提醒
select * from 日程安排 where datediff('minute', f开始时间, getdate())>5
10. 一条 SQL 分页
select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段
具体实现(top 后不能直接跟变量):
declare @start int,@end int
declare @sql nvarchar(600)
set @sql='select top '+str(@end-@start+1)+' * from T where rid not in(select top '+str(@start-1)+' Rid from T where Rid>-1)'
exec sp_executesql @sql
Rid 为标识列。top 的字段若是逻辑索引,查询结果可能和表中不一致(索引数据可能与表不一致,走索引时先查索引)。
11. 前 10 条 / 每组最大值
select top 10 * from table1 where 范围
每一组 b 值相同的数据中对应 a 最大的记录(论坛月排行、热销分析、按科目排名等):
select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)
四、提升:差集、随机、去重、元数据
12. EXCEPT 多表差集
(select a from tableA ) except (select a from tableB) except (select a from tableC)
13. 随机 10 条 / 随机选择
select top 10 * from tablename order by newid()
select newid()
14. 删除重复记录
delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)
select distinct * into temp from tablename
delete from tablename
insert into tablename select * from temp
评价:第二种牵连大量数据移动,不适合大容量。外部导入造成重复时:
alter table tablename
add column_b int identity(1,1)
delete from tablename where column_b not in(
select max(column_b) from tablename group by column1,column2,...)
alter table tablename drop column column_b
15. 列出所有表名 / 列名
select name from sysobjects where type='U' -- U 代表用户表
select name from syscolumns where id=object_id('TableName')
16. CASE 透视
select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type
显示结果示意:电脑 A 1;光盘 B 2;手机 C 3 等按 type 分组后横向展开 vender。
17. 初始化表 / 选第 10 到 15 条
TRUNCATE TABLE table1
select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc
一句话总结:库表索引视图用 DDL 管,查询用 SELECT/JOIN/GROUP;分页、去重、随机、CASE 透视是业务里最常抄的几段,注意 top 不能直接跟变量。