【SQL中一些特别地方特别解法】
本帖最后由 feixianxxx 于 2010-03-22 14:17:50 编辑 详见博客地址:http://blog.csdn.net/feixianxxx/archive/2010/03/21/5402391.aspx
/*----------------------------------
*auther:Poofly
*date:2010.3.14
*VERSION:
Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86)
Jul 19 2008
Copyright (c) 1988-2008 Microsoft Corporation
Enterprise Evaluation Edition on Windows NT 6.1 <X86> (Build 7600: )
*转载请注明出处
*更多精彩内容,请进http://blog.csdn.net/feixianxxx
------------------------------------*/
--收集一些东西来写写
--环境
create table test_1 (a int ,b int)
create table test_2 (c int, d int)
insert test_1 select 1,2 union all select 1,null union all select 3,4
insert test_2 select 1,2 union all select 1,null
-- except
select * from test_1
except
select * from test_2
/*
a b
----------- -----------
3 4
*/
-- not exists
select * from test_1
where not exists(select * from test_2 where a=c and b=d)
/*
a b
----------- -----------
1 NULL --这条记录对于test_1来说是唯一的
3 4
*/
--环境
create table test_3
(
id int,
value int
)
insert test_3 values(1,12)
insert test_3 values(1,1)
insert test_3 values(1,3)
insert test_3 values(1,2)
insert test_3 values(1,6)
insert test_3 values(2,1)
insert test_3 values(2,2)
insert test_3 values(2,4)
insert test_3 values(2,3)
go
--OVER
SELECT ID,
[SUM]=SUM(VALUE) OVER(),
[AVG]=AVG(VALUE) OVER(),
[COUNT]=COUNT(VALUE) OVER(),
[MAX]=MAX(VALUE) OVER()
FROM test_3
--子查询
select id,
[SUM]=(select SUM(VALUE) from test_3 where l.id=id),
[AVG]=(select AVG(VALUE) O from test_3 where l.id=id),
[COUNT]=(select COUNT(VALUE) from test_3 where l.id=id),
[MAX]=(select MAX(VALUE) from test_3 where l.id=id)
FROM test_3 l
--group by
SELECT ID,
[SUM]=SUM(VALUE),
[AVG]=AVG(VALUE) ,
[COUNT]=COUNT(VALUE) ,
[MAX]=MAX(VALUE)
FROM test_3
group by id
--环境这个字符串优点是无论是否有好的索引,因为它只扫描一次(这里数据量太小)
create table test_4 (id int, a int, b int , c int)
insert test_4 select
1,2,3,4 union all select
1,3,5,4 union all select
1,3,7,4 union all select
1,3,7,8 union all select
2,2,3,4 union all select
2,5,3,8 union all select
2,5,3,8 union all select
2,7,3,8 union all select
2,1,9,9
go
--字符串
select
ID,
a=SUBSTRING(COL,1,5),
b=SUBSTRING(COL,6,5),
c=SUBSTRING(COL,11,5)
from (
select ID,
MAX(CAST(a as char(5))+CAST(b as char(5))+CAST(c as char(5))) as col
from test_4
group by ID
) l
--子查询
select *
from test_4 k
where not exists(select * from test_4
where id=k.id and (a>k.a or a=k.a and b>k.b or a=k.a and b=k.b and c>k.c))
/*
ID a b c
----------- ---------- ---------- ----------
1 3 7 8
2 7 3 8
*/
--环境
create table test_5(empid int, name varchar(10))
insert test_5 select
1,'a'union all select
1,'b' union all select
1,'c'union all select
1,'d'union all select
2,'a' union all select
2,'t'union all select
2,'v'
select
empid,
name=MAX(case when rn=1 then name else '' end)+MAX(case when rn=2 then ','+name else '' end)
+MAX(case when rn=3 then ','+name else '' end)+MAX(case when rn=4 then ','+name else '' end)
from(
select empid,name,
(select COUNT(*) from test_5 where k.empid=empid and k.name>=name) as rn
from test_5 k )z
group by empid
--xml
select empid,
name=stuff((select ','+name as [text()] from test_5 where k.empid=empid order by name for XML PATH('')),1,1,'')
from test_5 k
group by empid
/*
empid name
----------- -------------------------------------------
1 a,b,c,d
2 a,t,v
*/
注意点:可以利用TOP + ORDER BY 巧妙解决取中值的问题,而且在SQL2000也可以方便使用
--环境
create table test_6(rq varchar(8), ddsj int)
insert into test_6
select
'200805',30 union all select
'200805',40 union all select
'200805',50 union all select
'200805',20 union all select
'200806',250 union all select
'200806',200 union all select
'200806',310 union all select
'200806',100 union all select
'200806',130
go
--TOP + ORDER BY 求中值(NTILE同样的效果)
select rq,
(
(
select MAX(ddsj) as ddsj
from (select top 50 percent ddsj from test_6 where rq=k.rq order by ddsj ) k
)+
(
select MIN(ddsj) as ddsj
from (select top 50 percent ddsj from test_6 where rq=k.rq order by ddsj desc) k
)
)/2 as ddsj
from test_6 k
group by rq
--利用位置的收尾呼应~
;with cte as
(
select *,ROW_NUMBER() over(partition by rq order by ddsj ) as rn1,
ROW_NUMBER() over(partition by rq order by ddsj desc ) as rn2
from test_6
)
select rq,ddsj=AVG(ddsj)
from
cte
where abs(rn1-rn2)<=1
group by rq
/*
rq ddsj
-------- -----------
200805 35
200806 200
*/
--环境
create table test_7
(
id int,
col1 int,
col2 int
)
create index in_col1 on test_7(col1)
insert test_7 values(1,1,3)
insert test_7 values(1,1,2)
insert test_7 values(1,2,3)
go 100000
insert test_7 values(1,3,3)
insert test_7 values(1,3,1)
insert test_7 values(2,2,3)
insert test_7 values(2,2,5)
insert test_7 values(2,4,9)
go
--or
select *
from test_7
where col1<1 or (col1=1 and col2<3)
--and
select *
from test_7
where col1<=1 and (col1<1 or col2<3)
--环境
create table test_8(id int identity(1,1),a int)
insert test_8 select 1
insert test_8 select 2
insert test_8 select 3
insert test_8 select 7
insert test_8 select 9
go
select ID+0 as id ,A into #1 from test_8
insert #1(a) select 8
select * from #1
/*
id A
----------- -----------
NULL 8 ---没有自增
1 1
2 2
3 3
4 7
5 9
*/