SqlServer中很少被用到的一些计算技巧!
发布时间:2020-12-12 13:17:46 所属栏目:MsSql教程 来源:网络整理
导读:--1.【行列转换】--列转行USE tempdbGOIF (OBJECT_ID('DEPT') IS NOT NULL) DROP TABLE DEPT CREATE TABLE DEPT(NAME VARCHAR(5),COL1 INT,COL2 INT,COL3 INT,COL4 INT,COL5 INT,COL6 INT) INSERT INTO DEPTSELECT 'A',10,50,20,30,80UNION ALLSELECT 'B',40
--1.【行列转换】 --列转行 USE tempdb GO IF (OBJECT_ID('DEPT') IS NOT NULL) DROP TABLE DEPT CREATE TABLE DEPT(NAME VARCHAR(5),COL1 INT,COL2 INT,COL3 INT,COL4 INT,COL5 INT,COL6 INT) INSERT INTO DEPT SELECT 'A',10,50,20,30,80 UNION ALL SELECT 'B',40 UNION ALL SELECT 'C',5,80 SELECT * FROM DEPT select NAME,NEWCOLUMNS,value --into #TEMP from DEPT unpivot( value for NEWCOLUMNS in(COL1,COL2,COL3,COL4,COL5,COL6) ) as t /* NAME NEWCOLUMNS value A COL1 10 A COL2 50 A COL3 20 A COL4 30 A COL5 0 A COL6 80 B COL1 50 B COL2 20 B COL3 10 B COL4 10 B COL5 20 B COL6 40 C COL1 5 C COL2 0 C COL3 0 C COL4 10 C COL5 0 C COL6 80 */ --行转列 select * from #TEMP select * from #TEMP PIVOT( max(value) for NEWCOLUMNS in(COL1,COL6) ) as t /* NAME COL1 COL2 COL3 COL4 COL5 COL6 A 10 50 20 30 0 80 B 50 20 10 10 20 40 C 5 0 0 10 0 80 */ --2.【每行中的数值统计:每行中各列数据的最大值、最小值、平均值】 USE tempdb GO IF (OBJECT_ID('DEPT') IS NOT NULL) DROP TABLE DEPT CREATE TABLE DEPT(NAME VARCHAR(5),80 SELECT *,MaxValue=(select MAX(COL) FROM ( SELECT COL1 AS COL UNION ALL SELECT COL2 UNION ALL SELECT COL3 UNION ALL SELECT COL4 UNION ALL SELECT COL5 UNION ALL SELECT COL6 ) A),MINValue=(select MIN(COL) FROM ( SELECT COL1 AS COL UNION ALL SELECT COL2 UNION ALL SELECT COL3 UNION ALL SELECT COL4 UNION ALL SELECT COL5 UNION ALL SELECT COL6 ) B),AVGValue=(select AVG(COL) FROM ( SELECT COL1 AS COL UNION ALL SELECT COL2 UNION ALL SELECT COL3 UNION ALL SELECT COL4 UNION ALL SELECT COL5 UNION ALL SELECT COL6 ) c) FROM DEPT /* 结果: NAME COL1 COL2 COL3 COL4 COL5 COL6 MaxValue MINValue AVGValue A 10 50 20 30 0 80 80 0 31 B 50 20 10 10 20 40 50 10 25 C 5 0 0 10 0 80 80 0 15 */ --3.【每列中的数值统计】 USE tempdb GO IF (OBJECT_ID('DEPT') IS NOT NULL) DROP TABLE DEPT CREATE TABLE DEPT(ID INT IDENTITY (1,1),VALUE INT) INSERT INTO DEPT(VALUE) VALUES(90),(86),(60),(80),(100),(0),(85),(65) SELECT * FROM DEPT select ID,VALUE,id = dense_rank() over(order by VALUE desc),比例 = VALUE*100.0/sum(VALUE)OVER(),最大差值 = max(VALUE)OVER() - VALUE,最小差值 = VALUE - min(VALUE)OVER() from DEPT /*结果: ID VALUE id 比例 最大差值 最小差值 5 100 1 15.479876160990 0 100 1 90 2 13.931888544891 10 90 2 86 3 13.312693498452 14 86 8 85 4 13.157894736842 15 85 9 80 5 12.383900928792 20 80 4 80 5 12.383900928792 20 80 10 65 6 10.061919504643 35 65 3 60 7 9.287925696594 40 60 6 0 8 0.000000000000 100 0 7 0 8 0.000000000000 100 0 */ --4.【某部门的所有上级机构或下级机构】 IF (OBJECT_ID('DEPT') IS NOT NULL) DROP TABLE DEPT CREATE TABLE DEPT(ID INT,PID INT,NAME VARCHAR(20)) INSERT INTO DEPT VALUES (1,'总公司'),(2,1,'研发部'),(3,'销售部'),(4,'财务部'),(5,2,'研发一部'),(6,'研发二部'),(7,3,'销售一部'),(8,'销售二部'),(9,'销售三部'),(10,'小组A'),(11,'小组B') SELECT * FROM DEPT --求一个部门的所有下级,如[研发部] 的所有下级' --条件:所有部门的父id都等于[研发部]的ID,取到都是下级的 ;WITH D(ID,PID,NAME,LVL) AS( SELECT ID,0 LVL FROM DEPT WHERE NAME='研发部' UNION ALL SELECT DEPT.ID,DEPT.PID,DEPT.NAME,LVL +1 FROM DEPT INNER JOIN D ON DEPT.PID=D.ID ) SELECT * FROM D --求一个部门的所有上级,如[研发一部] 的所有上级' ;WITH D(ID,0 LVL FROM DEPT WHERE NAME='研发一部' UNION ALL SELECT DEPT.ID,LVL +1 FROM DEPT INNER JOIN D ON DEPT.ID=D.PID ) SELECT * FROM D SELECT * FROM DEPT INNER JOIN (SELECT ID,NAME FROM DEPT WHERE NAME='研发部' ) TAB ON DEPT.ID=TAB.ID --5.【添加 删除 更新 时取出数据】 drop table #temp SELECT * FROM DEPT --继续用上一步的表 SELECT NAME into #temp FROM DEPT WHERE 1<>1 SELECT * FROM #temp insert into #temp(NAME) output inserted.NAME --into tableName(colName) 输出可插入到其他表 SELECT NAME FROM DEPT Delete DEPT output deleted.NAME where PID = 3 UPDATE #temp SET NAME = '集团' OUTPUT Inserted.NAME Old,Deleted.NAME New WHERE NAME = '总公司' --6.【Merge into】 /* drop table #a; drop table #b; */ create table #a (aid int null,aname varchar(10) null); create table #b (bid int null,bname varchar(10) null); insert into #a values(1,'Value1'); insert into #a values(3,'Value3'); insert into #a values(4,'Value4'); insert into #b values(1,'New Value1'); insert into #b values(2,'New Value2'); insert into #b values(3,'New Value3'); merge into #a using #b on #a.aid=#b.bid when matched --and #a.aid = 1 (可增加条件) then update set #a.aname=#b.bname when not matched then insert values(#b.bid,#b.bname) when not matched by source then delete; --必须分号结束 select * from #a; select * from #b; --7.【多列查询同一值简化】 select * from tableName where COL1=100 or COL2=100 or COL3=100 or COL4=100 or COL5=100 or COL6=100 --简化操作 select * from tableName where 100 in(COL1,COL6) --8.【同列字符相连】 use tempdb go -- drop table tb create table tb(id int,value varchar(30)) go insert into tb values (1,'aa'),(1,'bb'),'aaa'),'bbb'),'ccc') select * from tb SELECT DISTINCT id,STUFF((SELECT ','+value FROM tb B WHERE A.id=B.id FOR XML PATH('')),'') AS value FROM tb A /*结果: id value --- ----------- 1 aa,bb 2 aaa,bbb,ccc */ --逆转换 use tempdb go -- drop table tb create table tb(id int,value varchar(30)) go insert into tb values(1,'aa,bb') insert into tb values(2,'aaa,ccc') select * from tb select A.id,B.value from( select id,[value] = convert(xml,' <root> <v>' + replace([value],',' </v> <v>') + ' </v> </root>') from tb )A outer apply( select value = N.v.value('.','varchar(100)') from A.[value].nodes('/root/v') N(v) )B /*结果: id value -- ----- 1 aa 1 bb 2 aaa 2 bbb 2 ccc */ --8.【同列数值分组累加】 drop table #temp create table #temp(name varchar(1),value int) insert #temp select 'a',1 union all select 'b',5 union all select 'a',3 union all select 'a',5 union all select 'b',9 union all select 'b',5 select * from #temp ;with tabA as( select row_number() over(partition by name order by name) id,name,value from #temp ),tabB AS( select id,value,value as total from tabA WHERE id = 1 union all select a.id,a.name,a.value,a.value+b.total from tabA a inner join tabB b on a.name=b.name and a.id=b.id+1 ) select * from tabB order by name,id /*结果: id name value total -- ---- ----- ---- 1 a 3 3 2 a 5 8 3 a 1 9 1 b 5 5 2 b 9 14 3 b 5 19 */ --【一条sql语句执行N次】 CREATE TABLE TB(ID INT IDENTITY (1,NAME VARCHAR(40)) INSERT INTO TB(NAME) SELECT 'KK'+CONVERT(VARCHAR(5),isnull(@@IDENTITY,0)+1) GO 10 --【随机取出N条记录】 select top 5 * from tableName order by newid() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |