zoukankan      html  css  js  c++  java
  • MSSQL扫盲系列(4)系统函数

    为了能够演示,先建立了三张表,具体SQL如下:

    View Code
    CREATE TABLE POSTTB (ID INT IDENTITY(1,1) PRIMARY KEY,NAME NVARCHAR(20) NOT NULL)
    --职位对照表
    INSERT INTO POSTTB VALUES('项目经理')
    INSERT INTO POSTTB VALUES('架构师')
    INSERT INTO POSTTB VALUES('开发人员')
    INSERT INTO POSTTB VALUES('美工')
    --插入数据

    CREATE TABLE EMPLOYEETB(ID INT IDENTITY(1,1) PRIMARY KEY ,NAME NVARCHAR(20) NOT NULL)
    --人员对照表
    INSERT INTO EMPLOYEETB VALUES('周一仙')
    INSERT INTO EMPLOYEETB VALUES('张小凡')
    INSERT INTO EMPLOYEETB VALUES('碧瑶')
    INSERT INTO EMPLOYEETB VALUES('陆雪琪')
    INSERT INTO EMPLOYEETB VALUES('曾书书')
    INSERT INTO EMPLOYEETB VALUES('云天河')
    INSERT INTO EMPLOYEETB VALUES('韩菱纱')
    INSERT INTO EMPLOYEETB VALUES('柳梦璃')
    INSERT INTO EMPLOYEETB VALUES('慕容紫英')
    INSERT INTO EMPLOYEETB VALUES('玄霄')
    --插入数据,诛仙+仙4

    CREATE TABLE SALARYTB (ID INT IDENTITY(1,1),
    EMPLOYEETBID INT REFERENCES EMPLOYEETB(ID),
    SALARY INT NOT NULL,
    [MONTH] DATETIME NOT NULL,
    [POSITION] INT REFERENCES POSTTB(ID))
    --工资表

    INSERT INTO SALARYTB VALUES(1,8500,'2012-1-1',1)
    INSERT INTO SALARYTB VALUES(1,9500,'2012-2-1',1)
    INSERT INTO SALARYTB VALUES(1,7500,'2012-3-1',1)

    INSERT INTO SALARYTB VALUES(2,1800,'2012-1-1',3)
    INSERT INTO SALARYTB VALUES(2,2000,'2012-2-1',3)
    INSERT INTO SALARYTB VALUES(2,1800,'2012-3-1',3)

    INSERT INTO SALARYTB VALUES(3,2100,'2012-1-1',4)
    INSERT INTO SALARYTB VALUES(3,2500,'2012-2-1',4)
    INSERT INTO SALARYTB VALUES(3,2200,'2012-3-1',4)

    INSERT INTO SALARYTB VALUES(4,2100,'2012-1-1',4)
    INSERT INTO SALARYTB VALUES(4,2800,'2012-2-1',4)
    INSERT INTO SALARYTB VALUES(4,2000,'2012-3-1',4)

    INSERT INTO SALARYTB VALUES(5,4000,'2012-1-1',2)
    INSERT INTO SALARYTB VALUES(5,4100,'2012-2-1',2)
    INSERT INTO SALARYTB VALUES(5,3900,'2012-3-1',2)

    INSERT INTO SALARYTB VALUES(6,3100,'2012-1-1',3)
    INSERT INTO SALARYTB VALUES(6,3500,'2012-2-1',3)
    INSERT INTO SALARYTB VALUES(6,3000,'2012-3-1',3)

    INSERT INTO SALARYTB VALUES(7,6500,'2012-1-1',1)
    INSERT INTO SALARYTB VALUES(7,7000,'2012-2-1',1)
    INSERT INTO SALARYTB VALUES(7,7200,'2012-3-1',1)

    INSERT INTO SALARYTB VALUES(8,3500,'2012-1-1',4)
    INSERT INTO SALARYTB VALUES(8,3400,'2012-2-1',4)
    INSERT INTO SALARYTB VALUES(8,3200,'2012-3-1',4)

    INSERT INTO SALARYTB VALUES(9,4300,'2012-1-1',2)
    INSERT INTO SALARYTB VALUES(9,4200,'2012-2-1',2)
    INSERT INTO SALARYTB VALUES(9,4700,'2012-3-1',2)

    INSERT INTO SALARYTB VALUES(10,2800,'2012-1-1',3)
    INSERT INTO SALARYTB VALUES(10,2300,'2012-2-1',3)
    INSERT INTO SALARYTB VALUES(10,2100,'2012-3-1',3)
    --插入数据

    最常用的几个聚合函数 

    AVG--求平局值

    View Code
    --职位薪水检查

    --查询每种职位每月的平均薪水
    SELECT POSTTB.NAME 职位,MONTH(SALARYTB.[MONTH]) 月份,AVG(SALARYTB.SALARY) AS 平均工资
    FROM SALARYTB
    JOIN POSTTB ON SALARYTB.POSITION=POSTTB.ID
    GROUP BY SALARYTB.POSITION,SALARYTB.[MONTH],POSTTB.NAME
    ORDER BY 平均工资 DESC

    SELECT POSTTB.NAME 职位,MONTH(SALARYTB.[MONTH]) 月份,AVG(SALARYTB.SALARY) AS 平均工资
    FROM SALARYTB,POSTTB
    WHERE SALARYTB.POSITION=POSTTB.ID
    GROUP BY SALARYTB.POSITION,SALARYTB.[MONTH],POSTTB.NAME
    ORDER BY 平均工资 DESC

    --查询每种职位1月的平均薪水
    SELECT POSTTB.NAME 职位,AVG(SALARYTB.SALARY) AS 平均工资
    FROM SALARYTB JOIN POSTTB ON SALARYTB.POSITION=POSTTB.ID
    WHERE MONTH(SALARYTB.[MONTH])=1
    GROUP BY SALARYTB.POSITION ,POSTTB.NAME
    ORDER BY 平均工资 DESC

    SELECT POSTTB.NAME 职位,AVG(SALARYTB.SALARY) AS 平均工资
    FROM SALARYTB,POSTTB
    WHERE SALARYTB.POSITION=POSTTB.ID AND MONTH(SALARYTB.[MONTH])=1
    GROUP BY SALARYTB.POSITION ,POSTTB.NAME
    ORDER BY 平均工资 DESC

    --查询每种职位这三个月的平均薪水
    SELECT POSTTB.NAME 职位,AVG(SALARYTB.SALARY) AS 平均工资
    FROM SALARYTB
    JOIN POSTTB ON SALARYTB.POSITION=POSTTB.ID
    GROUP BY SALARYTB.POSITION ,POSTTB.NAME
    ORDER BY 平均工资 DESC

    SELECT POSTTB.NAME 职位,AVG(SALARYTB.SALARY) AS 平均工资
    FROM SALARYTB,POSTTB
    WHERE SALARYTB.POSITION=POSTTB.ID
    GROUP BY SALARYTB.POSITION ,POSTTB.NAME
    ORDER BY 平均工资 DESC

    --个人薪水检查

    --查询所有人三个月的平均薪水
    SELECT EMPLOYEETB.NAME 职位,AVG(SALARYTB.SALARY) AS 平均工资
    FROM SALARYTB JOIN EMPLOYEETB ON SALARYTB.EMPLOYEETBID=EMPLOYEETB.ID
    GROUP BY SALARYTB.EMPLOYEETBID ,EMPLOYEETB.NAME
    ORDER BY 平均工资 DESC

    SELECT EMPLOYEETB.NAME 职位,AVG(SALARYTB.SALARY) AS 平均工资
    FROM SALARYTB , EMPLOYEETB WHERE SALARYTB.EMPLOYEETBID=EMPLOYEETB.ID
    GROUP BY SALARYTB.EMPLOYEETBID ,EMPLOYEETB.NAME
    ORDER BY 平均工资 DESC

    --查询所有人前两个月的平均薪水
    SELECT EMPLOYEETB.NAME 职位,AVG(SALARYTB.SALARY) AS 平均工资
    FROM SALARYTB JOIN EMPLOYEETB ON SALARYTB.EMPLOYEETBID=EMPLOYEETB.ID
    WHERE MONTH(SALARYTB.[MONTH]) BETWEEN 1 AND 2
    GROUP BY SALARYTB.EMPLOYEETBID ,EMPLOYEETB.NAME
    ORDER BY 平均工资 DESC

    SELECT EMPLOYEETB.NAME 职位,AVG(SALARYTB.SALARY) AS 平均工资
    FROM SALARYTB , EMPLOYEETB
    WHERE SALARYTB.EMPLOYEETBID=EMPLOYEETB.ID AND MONTH(SALARYTB.[MONTH]) BETWEEN 1 AND 2
    GROUP BY SALARYTB.EMPLOYEETBID ,EMPLOYEETB.NAME
    ORDER BY 平均工资 DESC

     COUNT--计数

    View Code
    --获取所有人数
    SELECT COUNT(DISTINCT E.NAME) 人数 FROM EMPLOYEETB E

    --获取每个职位上的人数
    SELECT POSTTB.NAME 职位,COUNT(DISTINCT SALARYTB.EMPLOYEETBID) 人数
    FROM SALARYTB
    JOIN POSTTB ON SALARYTB.POSITION=POSTTB.ID
    GROUP BY POSTTB.NAME

    SELECT POSTTB.NAME 职位,COUNT(DISTINCT SALARYTB.EMPLOYEETBID) 人数
    FROM SALARYTB,POSTTB
    WHERE SALARYTB.POSITION=POSTTB.ID
    GROUP BY POSTTB.NAME


    --后面这一部分是附带的
    --
    获取每个职位上的人
    SELECT DISTINCT POSTTB.NAME 职位 ,EMPLOYEETB.NAME 姓名
    FROM SALARYTB
    JOIN EMPLOYEETB ON SALARYTB.EMPLOYEETBID=EMPLOYEETB.ID
    JOIN POSTTB ON SALARYTB.[POSITION]=POSTTB.ID
    --直接使用DISTINCT
    ;WITH T AS
    (SELECT POSTTB.NAME 职位 ,EMPLOYEETB.NAME 姓名
    FROM SALARYTB
    JOIN EMPLOYEETB ON SALARYTB.EMPLOYEETBID=EMPLOYEETB.ID
    JOIN POSTTB ON SALARYTB.[POSITION]=POSTTB.ID)
    SELECT * FROM T UNION SELECT * FROM T
    --消除重复列
    ;WITH T AS
    (SELECT POSTTB.NAME 职位 ,EMPLOYEETB.NAME 姓名
    FROM SALARYTB
    JOIN EMPLOYEETB ON SALARYTB.EMPLOYEETBID=EMPLOYEETB.ID
    JOIN POSTTB ON SALARYTB.[POSITION]=POSTTB.ID)
    SELECT * FROM T INTERSECT SELECT * FROM T
    --消除重复列

    --合并列
    ;WITH T AS
    (SELECT DISTINCT POSTTB.NAME 职位 ,EMPLOYEETB.NAME 姓名
    FROM SALARYTB
    JOIN EMPLOYEETB ON SALARYTB.EMPLOYEETBID=EMPLOYEETB.ID
    JOIN POSTTB ON SALARYTB.[POSITION]=POSTTB.ID)
    SELECT 职位,姓名 FROM(
    SELECT DISTINCT 职位 FROM T
    ) A
    OUTER APPLY(
    SELECT
    [姓名]= STUFF(
    REPLACE(
    REPLACE(
    (SELECT 姓名 FROM T WHERE 职位 = A.职位 FOR XML AUTO),
    '<T 姓名="', ','),
    '"/>', ''),
    1, 1, '')
    )N
    --这个比较有难度

     SUM--求和

    View Code
    --求公司每个月分别发出多少薪水
    SELECT MONTH(S.[MONTH]) 月份, SUM(S.SALARY) 总薪水
    FROM SALARYTB S
    GROUP BY S.[MONTH]

    --求公司1月发出多少薪水
    SELECT MONTH(S.[MONTH]) 月份, SUM(S.SALARY) 总薪水
    FROM SALARYTB S WHERE MONTH(S.[MONTH])=1
    GROUP BY S.[MONTH]

    --求每个员工三个月总共领了多少薪水
    SELECT E.NAME 姓名, SUM(S.SALARY) 总薪水
    FROM SALARYTB S
    JOIN EMPLOYEETB E ON S.EMPLOYEETBID=E.ID
    GROUP BY E.NAME
    ORDER BY 总薪水 DESC

    --求每个职位三个月总共领了多少薪水
    SELECT P.NAME 姓名, SUM(S.SALARY) 总薪水
    FROM SALARYTB S
    JOIN POSTTB P ON S.POSITION=P.ID
    GROUP BY P.NAME
    ORDER BY 总薪水 DESC

    --求每个职位每个月总共领了多少薪水
    SELECT P.NAME 姓名,MONTH(S.[MONTH]) 月份,SUM(S.SALARY) 总薪水
    FROM SALARYTB S
    JOIN POSTTB P ON S.POSITION=P.ID
    GROUP BY P.NAME,S.[MONTH]
    ORDER BY 总薪水 DESC

     MAX,MIN--最大最小值(这一部分是有一些难度)

    View Code
    --查询每个员工最高薪水的月份
    WITH T AS (
    SELECT MAX(S.SALARY) SALARY,S.EMPLOYEETBID ID
    FROM SALARYTB S
    GROUP BY S.EMPLOYEETBID)
    SELECT E.NAME 姓名, MONTH(S.[MONTH]) 月份,T.SALARY 薪水
    FROM T
    JOIN EMPLOYEETB E ON T.ID=E.ID
    JOIN SALARYTB S ON S.SALARY=T.SALARY AND S.EMPLOYEETBID=T.ID


    WITH T AS (
    SELECT MIN(S.SALARY) SALARY,S.EMPLOYEETBID ID
    FROM SALARYTB S
    GROUP BY S.EMPLOYEETBID)
    SELECT E.NAME 姓名, MONTH(S.[MONTH]) 月份,T.SALARY 薪水
    FROM T
    JOIN EMPLOYEETB E ON T.ID=E.ID
    JOIN SALARYTB S ON S.SALARY=T.SALARY AND S.EMPLOYEETBID=T.ID

    --求各月工资最高最低的人
    SELECT MONTH(S.[MONTH]) 月份, T.SALARY 薪水,E.NAME 姓名 FROM
    (SELECT MAX(S.SALARY) SALARY,S.[MONTH]
    FROM SALARYTB S GROUP BY S.[MONTH] ) T
    JOIN SALARYTB S ON T.SALARY=S.SALARY AND S.[MONTH] = T.[MONTH]
    JOIN EMPLOYEETB E ON S.EMPLOYEETBID=E.ID
    ORDER BY 月份

    SELECT MONTH(S.[MONTH]) 月份, T.SALARY 薪水,E.NAME 姓名 FROM
    (SELECT MIN(S.SALARY) SALARY,S.[MONTH]
    FROM SALARYTB S GROUP BY S.[MONTH] ) T
    JOIN SALARYTB S ON T.SALARY=S.SALARY AND S.[MONTH] = T.[MONTH]
    JOIN EMPLOYEETB E ON S.EMPLOYEETBID=E.ID
    ORDER BY 月份


    ;WITH T AS (
    SELECT S.[MONTH] 月份,MAX(S.SALARY) 薪水
    FROM SALARYTB S
    GROUP BY S.[MONTH]
    )
    SELECT MONTH(S.[MONTH]) 月份,E.NAME 姓名,S.SALARY 薪水
    FROM SALARYTB S
    JOIN EMPLOYEETB E ON S.EMPLOYEETBID=E.ID
    WHERE S.SALARY IN (SELECT 薪水 FROM T)
    ORDER BY 月份

    ;WITH T AS (
    SELECT S.[MONTH] 月份,MIN(S.SALARY) 薪水
    FROM SALARYTB S
    GROUP BY S.[MONTH]
    )
    SELECT MONTH(S.[MONTH]) 月份,E.NAME 姓名,S.SALARY 薪水
    FROM SALARYTB S JOIN EMPLOYEETB E ON S.EMPLOYEETBID=E.ID
    WHERE S.SALARY IN (SELECT 薪水 FROM T)
    ORDER BY 月份

    SELECT MONTH(S.[MONTH]) 月份, T.SALARY 薪水,E.NAME 姓名 FROM
    (SELECT MAX(S.SALARY) SALARY,S.[MONTH]
    FROM SALARYTB S GROUP BY S.[MONTH] ) T
    JOIN SALARYTB S ON T.SALARY=S.SALARY AND S.[MONTH] = T.[MONTH]
    JOIN EMPLOYEETB E ON S.EMPLOYEETBID=E.ID
    ORDER BY 月份

    --查出每个部门每月薪水最高最低的人
    WITH T AS (
    SELECT MAX(S.SALARY) SALARY,S.[MONTH] [MONTH],S.POSITION POSTION
    FROM SALARYTB S GROUP BY S.[MONTH],S.POSITION
    )
    SELECT P.NAME 部门, MONTH(S.[MONTH]) 月份, T.SALARY 薪水,E.NAME 姓名 FROM SALARYTB S
    JOIN T ON T.SALARY=S.SALARY AND S.[MONTH] = T.[MONTH] AND S.POSITION=T.POSTION
    JOIN EMPLOYEETB E ON S.EMPLOYEETBID=E.ID
    JOIN POSTTB P ON S.POSITION=P.ID
    ORDER BY 部门,月份

    SELECT P.NAME 部门,MONTH(S.[MONTH]) 月份, T.SALARY 薪水,E.NAME 姓名 FROM (
    SELECT MAX(S.SALARY) SALARY,S.[MONTH] [MONTH],S.POSITION POSTION
    FROM SALARYTB S GROUP BY S.[MONTH],S.POSITION
    ) T
    JOIN SALARYTB S ON T.SALARY=S.SALARY AND S.[MONTH] = T.[MONTH] AND S.POSITION=T.POSTION
    JOIN EMPLOYEETB E ON S.EMPLOYEETBID=E.ID
    JOIN POSTTB P ON S.POSITION=P.ID
    ORDER BY 部门,月份



    WITH T AS (
    SELECT MIN(S.SALARY) SALARY,S.[MONTH] [MONTH],S.POSITION POSTION
    FROM SALARYTB S GROUP BY S.[MONTH],S.POSITION
    )
    SELECT P.NAME 部门, MONTH(S.[MONTH]) 月份, T.SALARY 薪水,E.NAME 姓名 FROM SALARYTB S
    JOIN T ON T.SALARY=S.SALARY AND S.[MONTH] = T.[MONTH] AND S.POSITION=T.POSTION
    JOIN EMPLOYEETB E ON S.EMPLOYEETBID=E.ID
    JOIN POSTTB P ON S.POSITION=P.ID
    ORDER BY 部门,月份

    SELECT P.NAME 部门,MONTH(S.[MONTH]) 月份, T.SALARY 薪水,E.NAME 姓名 FROM (
    SELECT MIN(S.SALARY) SALARY,S.[MONTH] [MONTH],S.POSITION POSTION
    FROM SALARYTB S GROUP BY S.[MONTH],S.POSITION
    ) T
    JOIN SALARYTB S ON T.SALARY=S.SALARY AND S.[MONTH] = T.[MONTH] AND S.POSITION=T.POSTION
    JOIN EMPLOYEETB E ON S.EMPLOYEETBID=E.ID
    JOIN POSTTB P ON S.POSITION=P.ID
    ORDER BY 部门,月份

     CONVERT

    View Code
    SELECT CONVERT(BIT,'1')
    --将整数字符串转化为BIT,负数不能转,只有'0'才能转换为0,其他的都是1
    SELECT CONVERT(INT,'-100'),CONVERT(INT,'0'),CONVERT(INT,'23')
    --将整数字符串转化为INT
    SELECT CONVERT(FLOAT,'12.023'),CONVERT(REAL,'89.145')
    --将整数字符串转化为FLOAT,REAL
    SELECT CONVERT(NVARCHAR(2),12),CONVERT(NVARCHAR(5),12.67),CONVERT(NVARCHAR,12.67777)
    --将数转化为字符串,长度可选

    SELECT CONVERT(DATETIME,'2012-8-9')
    --转换字符串为日期
    --
    --
    转换日期为字符串的格式很多
    --
    放个临时表,来看一下
    CREATE TABLE #(原值 DATETIME,代号 INT,结果 NVARCHAR(100))
    DECLARE @D DATETIME
    SET @D=GETDATE()
    DECLARE @I INT
    SET @I=0
    WHILE @I<132
    BEGIN
    INSERT INTO # SELECT @D,@I, CONVERT(NVARCHAR(100), @D, @I)
    SET @I=@I+1
    IF @I=15
    SET @I=20
    IF @I=26
    SET @I=100
    IF @I=115
    SET @I=120
    IF @I=122
    SET @I=130
    END
    INSERT INTO # SELECT @D,126, CONVERT(NVARCHAR(100), @D, 126)
    SELECT * FROM # ORDER BY 代号
    DROP TABLE #--及时干掉临时表,是个好习惯

    其他常用函数

    View Code
    --ISNULL
    SELECT ISNULL(NULL,'DEFAULTVALE'),ISNULL(12,'DEFAULTVALE')
    --检测第一个参数是否为空,如果为空,则使用后面的默认,否则就返回第一个参数值

    --数学函数

    --RAND
    SELECT RAND(),CONVERT(INT,RAND()*10),100+CONVERT(INT,RAND()*50)
    --获取随机小数,随机整数[0-10],[100-150]

    --日期函数

    --GETDATE,ISDATE
    SELECT GETDATE(),ISDATE('2012-8-9'),ISDATE('45546')
    --获取当前时间,检查所给字符串是否是日期,返回bit值

    --YEAR,MONTH,DAY
    SELECT YEAR(GETDATE()),MONTH(GETDATE()),DAY(GETDATE()),
    DATEDIFF(YEAR,'2011','2012-8-9'),DATEDIFF(YEAR,'2011-1-2','2990-2-3'),
    DATEDIFF(MONTH,'2011-3-1','2012-8-9'),DATEDIFF(MONTH,'2011-1-2','2990-2-3'),
    DATEDIFF(DAY,'2011-3-1','2011-8-9'),DATEDIFF(DAY,'2011-1-2','2011-1-3')
    --返回所给日期的的年,月,日,根据所给参数求出两个日期之间的差值(年,月,日)


    --字符串函数

    --LEN
    SELECT LEN('ABCD'),LEN('迷途小码农')
    --获取字符串长度

    --CHAR,NCHAR
    SELECT CHAR(65),CHAR(66),CHAR(67),
    NCHAR(20474),NCHAR(32769),
    NCHAR(23385),NCHAR(21435),NCHAR(20063)
    --将ASCII,UNICODE码转成字符

    --CHARINDEX
    SELECT CHARINDEX('','迷途小码农'),CHARINDEX('','迷途小码农'),
    CHARINDEX('D','ABCDEDD',5),CHARINDEX('DE','ABCDEDD')
    --从字符串中查找子串,第三个参数是起始位置,如果没有则返回0

    --LEFT,RIGHT,SUBSTRING
    SELECT LEFT(N'ABCDEFG',3),RIGHT(N'ABCDEFG',3),SUBSTRING(N'ABCDEFG',0,2)
    --返回所给字符串的左右端的几个字符所组成的串,截取字符串

    --LOWER,UPPER
    SELECT LOWER('ABCDEF'),UPPER('abcdef')
    --转化为大小写

    --LTRIM,RTRIM
    SELECT LTRIM(' ABC '),RTRIM(' ABC '),LTRIM(RTRIM(' ABC ')),
    LEN(LTRIM(' ABC ')),LEN(RTRIM(' ABC ')),LEN(LTRIM(RTRIM(' ABC ')))
    --剔除左右空格

    --REPLACE,REVERSE,STUFF
    SELECT REPLACE('ABCD','A','B'),REVERSE('ABCD'),
    STUFF('ABCDEFGHIJKLMN',2,5,'--')
    --替换,逆转,使用新串替换定长串
  • 相关阅读:
    HttpServer发送数据到kafka
    Leetcode[33]-Search in Rotated Sorted Array
    站在淘宝天猫两大平台背后的平台
    JSON格式的时间“/Date(1530104033000)/”格式转为正常的年-月-日 格式的代码
    火星坐标、百度坐标、WGS84坐标转换代码(JS、python版)
    echart 图例设置自定义图标?
    easyui datagrid实现拖动表头
    浮动闭合最佳方案:clearfix
    ASP.NET MVC提交LIST列表到后台接收不到数据
    mysql常用命令
  • 原文地址:https://www.cnblogs.com/wushilonng/p/2386047.html
Copyright © 2011-2022 走看看