SQL Serverのクエリーテクニック
11428 ワード
--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,' ' + replace([value], ',', ' ') + ' ') 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月累計が前の2ヶ月の場合、3月累計が前の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
*/