突然间来了兴趣,想整理一下由初步至较为复杂的SQL写法,下面的东西是想到哪儿写到哪儿,每一个层级的难度都会上升一点,大家凑合着看吧
假设有一张表TABLEA和表TABLEB,它们都各自有三个字段ID(自增长)、NAME(姓名)、SCORE(分数)、CREATEDATE(录入时间),其中两张表格可以通过ID进行关联
1、基本语句
1.1、查询
SELECT ID,NAME FROM TABLEA WHERE NAME LIKE '%TEST%' ORDER BY ID DESC
1.2、修改
UPDATE TABLEA SET NAME='张三',SCORE=30 WHERE ID=1
1.3、插入
INSERT INTO TABLEA(NAME,SCORE) VALUES('张三',40)
SELECT @@IDENTITY--此行为获取刚刚插入的数据的自增长ID
1.4、删除
DELETE FROM TABLEA WHERE ID=1
1.5、查询指定条数的记录
SELECT TOP 1 ID FROM TABLEA WHERE NAME LIKE '%TEST%'
1.6、修改指定条数的记录
UPDATE TOP(1) TABLEA
SET CustName='杨建平'
WHERE ID=1
1.7、删除指定条数的记录
DELETE TOP(1) FROM TABLEA WHERE NAME LIKE '%TEST%'
1.8、分组
SELECT NAME,COUNT(1) FROM TABLEA GROUP BY NAME
HAVING COUNT(1)>1---HAVING类似于分组语句中的WHERE
--注意,SELECT中除了函数外,其他的字段都必须要与GROUP保持一致,GROUP中的字段可以多,但不可以少
2、常用函数
2.1、日期格式函数
SELECT CONVERT(VARCHAR(10),CREATETIME,120) FROM TABLEA
此语句的作用是提取CREATEDATE字段,并格式化为“1900-01-01”这样的形式。
参数中的VARCHAR(10),即为保留前10位字符,后面的省掉,如果需要其他格式可以延长。
“120”即为指定的格式,其他格式还有以下这些:
0:05 16 2006 10:57AM
1:05/16/06
2:06.05.16
3:16/05/06
4:16.05.06
5:16-05-06
6:16 05 06
7:05 16, 06
8:10:57:46
9:05 16 2006 10:57:46:827AM
10:05-16-06
11:06/05/16
12:060516
13:16 05 2006 10:57:46:937
14:10:57:46:967
20:2006-05-16 10:57:47
21:2006-05-16 10:57:47.157
22:05/16/06 10:57:47 AM
23:2006-05-16
24:10:57:47
25:2006-05-16 10:57:47.250
100:05 16 2006 10:57AM
101:05/16/2006
102:2006.05.16
103:16/05/2006
104:16.05.2006
105:16-05-2006
106:16 05 2006
107:05 16, 2006
108:10:57:49
109:05 16 2006 10:57:49:437AM
110:05-16-2006
111:2006/05/16
112:20060516
113:16 05 2006 10:57:49:513
114:10:57:49:547
120:2006-05-16 10:57:49
121:2006-05-16 10:57:49.700
126:2006-05-16T10:57:49.827
130:18 14 27 10:57:49:907AM
131:18/04/14 10:57:49:920AM
2.2、行号函数
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS ROWNUM FROM CustInfo_Per
ROW_NUMBER() OVER(ORDER BY ID)即为取出的数据编制行号
2.3、数学函数
SELECT COUNT(1) FROM TABLEA---获取符合条件的记录条数
SELECT SUM(ID) FROM TABLEA---获取符合条件的字段值总和
SELECT SUM(ID) FROM TABLEA---获取符合条件的字段平均值
SELECT ABS(ID) FROM TABLEA---获取字段的绝对值
SELECT CEILING(ID,2) FROM TABLEA---获取大于或等于字段的最小整数
SELECT FLOOR(ID) FROM TABLEA--获取小于或等于字段的最大整数
SELECT POWER(ID,2) FROM TABLEA--获取字段的2次方,其他次方可以通过修改参数实现
SELECT MIN() FROM TABLEA---获取符合条件的最小值
SELECT MAX() FROM TABLEA---获取符合条件的最大值
2.4、字符串函数
SELECT LEN(NAME) FROM TABLEA---获取字段长度
SELECT DATALENGTH(NAME) FROM TABLEA---获取去除末尾空格后的字段长度
SELECT SUBSTRING(NAME,1,3) FROM TABLEA---取字符串,1即为开头第一个字符
SELECT RIGHT(NAME,3) FROM TABLEA---取末尾的三个字符串
SELECT UPPER(NAME) FROM TABLEA---取大写
SELECT LOWER(NAME) FROM TABLEA---取小写
2.5、日期函数
SELECT GETDATE()---获取当前时间
SELECT DATENAME(MM,CREATEDATE) FROM TABLEA--获取日期指定部分
SELECT DATEDIFF(dd, CREATEDATE,GETDATE()) FROM TABLEA--获取日期差
SELECT (dd,1,CREATEDATE) FROM TABLEA--在日期上面加1天
关于指定的日期部分标记:
yy 年份
mm 月份
dy 全年的第几天
dd 全月的第几天
wk 全年的第几周
dw 周几
hh 小时
mi 分钟
ss 秒
ms 毫秒
3、复杂语句
3.1、级联修改,即通过TABLEB的值,以及两张表格的关联字段,来直接修改TABLEA中的值
UPDATE TABLEA
SET NAME=WorkFlowSLA.NegatIsByLaw
FROM TABLEB
WHERE TABLEA.ID=TABLEB.ID AND TABLEA.CREATEDATE>'2020-01-01'
3.2、嵌套
SELECT *
FROM (SELECT COUNT(1) AS NUM,NAME FROM TABLEA GROUP BY NAME) AS A
WHERE A.NUM>10
3.3、初级分页
SELECT * FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ID ) AS ROWNUM,ID,NAME,CREATEDATE
) AS A
WHERE A.ROWNUM BETWEEN 11 AND 20--此为第2页,每页10条
3.4、临时表
SELECT * INTO #TEMP FROM TABLEA--解释:将TABLEA中的数据取出来,插入到临时表#TEMP中
SELECT * FROM #TEMP---从#TEMP中取出数据
DROP TABLE #TEMP---删除#TEMP表
说明:临时表的生命过程包括建立、操作、删除三个步骤,如果操作完以后不删除临时表,很可能会导致数据库中的临时表越来越多,影响性能。另外,构建临时表名时,尽量使用#TEMP+GUID的方式,要不然表名冲突,就会导致程序异常
3.5、大数据量分页
注:如果需要提取的字段极多、数据记录极多,可使用以下SQL,基本上可以解决九成以上的分页查询优化
SELECT * INTO #TEMP
FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ID) ROWNUM,NAME,CREATEDATE
FROM TABLEA
WHERE 1=1) AS A
WHERE A.ROWNUM BETWEEN 11 AND 20
SELECT * FROM #TEMP INNER JOIN TABLEA ON #TEMP.ID=TABLEA.ID
DROP TABLE #TEMP
3.6、清空数据库日志日志
--清空日志文件
USE DB --要清除的数据库名称
GO
DECLARE @LOGNAME VARCHAR(100)=''--日志文件名,不用动
SELECT @LOGNAME=name FROM SYS.database_files WHERE type_desc='LOG'
ALTER DATABASE DB SET RECOVERY SIMPLE WITH NO_WAIT
ALTER DATABASE DB SET RECOVERY SIMPLE
--要清除的数据库日志文件 替换 ''号里面的内容
DBCC SHRINKFILE (@LOGNAME , 0,TRUNCATEONLY)
ALTER DATABASE DB SET RECOVERY FULL WITH NO_WAIT
ALTER DATABASE DB SET RECOVERY FULL
3.7、级联查询
这个就不用给定的那张表格了,因为那里面没有上下级关系,这里直接用个部门表,根据指定的部门ID,提取其所有下级部门
WITH t(DataID,ParentId) as (
SELECT DataID, ParentId FROM DataDictionary WHERE DataID = 163
UNION ALL
SELECT t1.DataID,t1.ParentID FROM DataDictionary t1 JOIN t ON t1.ParentID=t.DataID
)
SELECT * FROM t order by DataID