SQL Server 一些查询技巧
--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,0,80
UNION ALL
SELECT 'B',50,20,10,10,20,40
UNION ALL
SELECT 'C',5,0,0,10,0,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,COL2,COL3,COL4,COL5,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),COL1 INT,COL2 INT,COL3 INT,COL4 INT,COL5 INT,COL6 INT)
INSERT INTO DEPT
SELECT 'A',10,50,20,30,0,80
UNION ALL
SELECT 'B',50,20,10,10,20,40
UNION ALL
SELECT 'C',5,0,0,10,0,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),(0),(85),(80),(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,0,'总公司'),
(2,1,'研发部'),
(3,1,'销售部'),
(4,1,'财务部'),
(5,2,'研发一部'),
(6,2,'研发二部'),
(7,3,'销售一部'),
(8,3,'销售二部'),
(9,3,'销售三部'),
(10,5,'小组A'),
(11,5,'小组B')
SELECT * FROM DEPT
--求一个部门的所有下级,如[研发部] 的所有下级'
--条件:所有部门的父id都等于[研发部]的ID,取到都是下级的
;WITH D(ID,PID,NAME,LVL)
AS(
SELECT ID,PID,NAME,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,PID,NAME,LVL)
AS(
SELECT ID,PID,NAME,0 LVL FROM DEPT WHERE NAME='研发一部'
UNION ALL
SELECT DEPT.ID,DEPT.PID,DEPT.NAME,LVL +1
FROM DEPT INNER JOIN D ON DEPT.ID=D.PID
)
SELECT * FROM D
SELECT * FROM DEPT INNER JOIN (SELECT ID,PID,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,COL2,COL3,COL4,COL5,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'),
(2,'aaa'),
(2,'bbb'),
(2,'ccc')
select * from tb
SELECT DISTINCT id,STUFF((SELECT ','+value FROM tb B WHERE A.id=B.id FOR XML PATH('')),1,1,'') 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,bbb,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,name,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,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()
年内按月累计(如:2月累计为前两个月的,3月累计为前三个月的)
CREATE TABLE T (tDate DATETIME,tValue INT)
INSERT INTO dbo.T
SELECT '2017-01-08',10 UNION
SELECT '2017-01-25',20 UNION
SELECT '2017-02-11',30 UNION
SELECT '2017-02-28',40 UNION
SELECT '2017-03-17',50 UNION
SELECT '2017-04-03',60 UNION
SELECT '2017-04-20',70 UNION
SELECT '2017-05-07',80 UNION
SELECT '2017-05-24',90
SELECT * FROM dbo.T;
SELECT MONTH(tDate) AS 月份,
(SELECT SUM(tValue) FROM dbo.T T1 WHERE MONTH(T1.tDate)<=MONTH(T.tDate)) 累计
FROM dbo.T
GROUP BY MONTH(tDate)
tDate tValue
----------------------- -----------
2017-01-08 00:00:00.000 10
2017-01-25 00:00:00.000 20
2017-02-11 00:00:00.000 30
2017-02-28 00:00:00.000 40
2017-03-17 00:00:00.000 50
2017-04-03 00:00:00.000 60
2017-04-20 00:00:00.000 70
2017-05-07 00:00:00.000 80
2017-05-24 00:00:00.000 90
(9 行受影响)
月份 累计
----------- -----------
1 30
2 100
3 150
4 280
5 450
(5 行受影响)
求x个月内产品逐月库存
if object_id('[huang]') is not null drop table [huang]
go
create table [huang]([年] int,[月] int,[产品] varchar(1),[未出库数量] int)
insert [huang]
select 2013,11,'A',100 union all
select 2014,1,'A',300 union all
select 2013,10,'B',1000 union all
select 2013,11,'B',1500 union all
select 2013,12,'B',3001
--------------开始查询--------------------------
;WITH d AS
(
SELECT CONVERT(VARCHAR(10),DATEADD(mm,number,'2013-11-01'),120)[date],b.产品
FROM master..spt_values cross JOIN (SELECT DISTINCT 产品 FROM [huang]) b
WHERE [type]='p' AND number>0 AND number<7 --这个7可以控制月份
),cte AS (
select ISNULL([年],YEAR(d.[date])) [年],ISNULL([月],month(d.[date])) [月],ISNULL(a.[产品],d.产品) 产品,ISNULL([未出库数量],0)[未出库数量],ROW_NUMBER()OVER(PARTITION BY ISNULL(a.[产品],d.产品) ORDER BY ISNULL([年],YEAR(d.[date])),ISNULL([月],month(d.[date]))) id
from [huang] a full JOIN d ON a.[年]=YEAR(d.[date]) AND a.[月]=MONTH(d.[date]) AND a.[产品]=d.产品
)
SELECT [年],[月],[产品],ISNULL((SELECT SUM([未出库数量] ) FROM cte b WHERE a.id>b.id AND a.[产品]=b.[产品]),0)[未出库数量]
FROM cte a
ORDER BY [产品],[年],a.月
/*
年 月 产品 未出库数量
----------- ----------- ---- -----------
2013 11 A 0
2013 12 A 100
2014 1 A 100
2014 2 A 400
2014 3 A 400
2014 4 A 400
2014 5 A 400
2013 10 B 0
2013 11 B 1000
2013 12 B 2500
2014 1 B 5501
2014 2 B 5501
2014 3 B 5501
2014 4 B 5501
2014 5 B 5501
*/
SQL Server 一些查询技巧的更多相关文章
- sql server 日期 查询技巧
CONVERT(varchar(100), SendTime, 23) –-sql里的字段SendTime参数 selectdateName(weekday,getDate());--返回当前星期 s ...
- 转载 50种方法优化SQL Server数据库查询
原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1 ...
- MS SQL Server数据库查询优化技巧
[摘 要]本文主要是对MS SQL Server数据库查询优化技巧进行了说明和分析,对索引使用.查询条件以及数据表的设计等进行了阐述.中国论文网 http://www.xzbu.com/2/view- ...
- Sql Server中查询今天、昨天、本周、上周、本月、上月数据
Sql Server中查询今天.昨天.本周.上周.本月.上月数据 在做Sql Server开发的时候有时需要获取表中今天.昨天.本周.上周.本月.上月等数据,这时候就需要使用DATEDIFF()函数及 ...
- Sql Server参数化查询之where in和like实现详解
where in 的参数化查询实现 首先说一下我们常用的办法,直接拼SQL实现,一般情况下都能满足需要 string userIds = "1,2,3,4"; using (Sql ...
- 【转】Sql Server参数化查询之where in和like实现之xml和DataTable传参
转载至: http://www.cnblogs.com/lzrabbit/archive/2012/04/29/2475427.html 在上一篇Sql Server参数化查询之where in和li ...
- 【转】Sql Server参数化查询之where in和like实现详解
转载至:http://www.cnblogs.com/lzrabbit/archive/2012/04/22/2465313.html 文章导读 拼SQL实现where in查询 使用CHARINDE ...
- SQL Server中查询用户的对象权限和角色的方法
--SQL Server中查询用户的对象权限和角色的方法 -- 查询用户的object权限 exec sp_helprotect NULL, 'sa' -- 查询用户拥有的role exec sp_h ...
- 优化SQL Server数据库查询方法
SQL Server数据库查询速度慢的原因有很多,常见的有以下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列 ...
随机推荐
- centos7 安装 telnet
https://blog.csdn.net/wfh6732/article/details/55062016/ https://blog.csdn.net/typa01_kk/article/deta ...
- idea ssm项目迁移到另一台机器上时出现不能正常启动项目的解决方案
首先右下角提示关联spring文件,关联之,然后启动,发现项目无法启动,然后开始排错 首先从这个日志里发现了这么一条提示信息 然后百度了一下,答案都是说 web.xml 之类的 spring拦截器问题 ...
- 轻量级直播服务器SRS安装及编译
最近由于公司开发的需要--互动会议,开始研究直播中的技术.由于自身没有接触过虚拟机导致在研究的过程中遇到了很大的问题,首先官方GitHub给出的文档并没有清晰的指出编译是需要通过何种方式进行编译?以下 ...
- DelayQueue 订单限时支付实例
1.订单实体 package com.zy.entity; import java.util.Date; import java.util.concurrent.Delayed; import jav ...
- Asp.Net_序列化、反序列化
.net序列化及反序列化 在我们深入探讨C#序列化和反序列化之前我们先要明白什么是序列化,它又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制.序列化就是把一个对象保存到一个文件或数据库 ...
- Js_Eval方法
定义和用法eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码. 语法eval(string) 其中参数string为必需.是要计算的字符串,其中含有要计算的 JavaScr ...
- Python数据信号处理库RadioDSP: 引入ThinkDSP实现思想
RadioDSP是针对无线通信领域的数字信号处理库,它采用了ThinkDSP的思想,对于无线通信中的IQ信号可以绘制频谱图和时域图.目前项目还在起始阶段,详细的代码可以参考链接: https://gi ...
- PAT甲题题解-1024. Palindromic Number (25)-大数运算
大数据加法给一个数num和最大迭代数k每次num=num+num的倒序,判断此时的num是否是回文数字,是则输出此时的数字和迭代次数如果k次结束还没找到回文数字,输出此时的数字和k 如果num一开始是 ...
- BugPhobia开发篇章:Beta阶段第IV次Scrum Meeting
0x01 :Scrum Meeting基本摘要 Beta阶段第四次Scrum Meeting 敏捷开发起始时间 2015/12/16 00:00 A.M. 敏捷开发终止时间 2015/12/16 23 ...
- 《Linux内核分析》课程第二周学习总结
姓名:何伟钦 学号:20135223 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...