【一些特别的地方和特别的解法】
来源:互联网 发布:阿里巴巴国际交易软件 编辑:程序博客网 时间:2024/04/24 12:14
详见博客地址:http://blog.csdn.net/feixianxxx/archive/2010/03/21/5402391.aspx
注意点:2个NULL值对于EXCEPT是相等的,不同于一般的筛选器.
ps:因为现有版本不支持 except all 所以EXCEPT使用时候会有一个排序的阶段,效率一般不太好
--2.OVER()子句
注意点:OVER()子句在多聚合情况下比在select 下的子查询效率 or GROUP BY 高很多
CTRL+L 可以发现 over的开销明显小于后者..其中子查询效率极差
--3.利用字符串解决带附加属性的问题
注意点:当需要附加属性来解决问题时候,一般会想到子查询,但是因为子查询需要良好的索引设计,所以不太好用.可以使用字符串来解决这个问题
--4.利用聚合实现字符串拼接
注意:不用XML、函数、临时表、游标去实现字符串的拼接
ps:该方法前提是name不能在同一组里出现重复,且每组内最大记录数不是很大。通过执行发现该方法效率优于XML
适合用于SQL2000中想实现字符串拼接但是又不想函数的情况下.
5.TOP + ORDER BY 求中值
注意点:可以利用TOP + ORDER BY 巧妙解决取中值的问题,而且在SQL2000也可以方便使用
在适用 缺点是没有合适的索引将会很慢
--6 OR 转变成AND
注意点:大家都知道OR在where条件出现时候,一般来说意味着索引的失效,只要筛选列上有一个没有索引的话.相比较而言,AND是有个索引就有个效果.所以我们有必要在能将OR转成AND的时候就转化.
通过执行计划可以看到 带AND的开销比OR少了倍,它用到了COL1上的索引
--7 利用计算表达式改变IDENTITY
注意:使用select into 表的时候如果有自增列 会把自增的属性也复制过去,可以通过计算表达式去去除这个自增属性
注意:在更新时也可以使用连续等于 @i=col=@i+1 <===> @i加后赋值给COL字段
- SQL code
- /*----------------------------------------------------------------------*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------------------------------------------------------------------------*/--收集一些东西来写写
注意点:2个NULL值对于EXCEPT是相等的,不同于一般的筛选器.
- SQL code
- --环境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,4insert 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 existsselect * from test_1where not exists(select * from test_2 where a=c and b=d)/*a b----------- -----------1 NULL --这条记录对于test_1来说是唯一的3 4*/
ps:因为现有版本不支持 except all 所以EXCEPT使用时候会有一个排序的阶段,效率一般不太好
--2.OVER()子句
注意点:OVER()子句在多聚合情况下比在select 下的子查询效率 or GROUP BY 高很多
- SQL code
- --环境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--OVERSELECT 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
CTRL+L 可以发现 over的开销明显小于后者..其中子查询效率极差
--3.利用字符串解决带附加属性的问题
注意点:当需要附加属性来解决问题时候,一般会想到子查询,但是因为子查询需要良好的索引设计,所以不太好用.可以使用字符串来解决这个问题
- SQL code
- --环境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 colfrom test_4 group by ID) l--子查询select * from test_4 kwhere 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 */
--4.利用聚合实现字符串拼接
注意:不用XML、函数、临时表、游标去实现字符串的拼接
- SQL code
- --环境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--xmlselect 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 kgroup by empid/*empid name----------- -------------------------------------------1 a,b,c,d2 a,t,v*/
ps:该方法前提是name不能在同一组里出现重复,且每组内最大记录数不是很大。通过执行发现该方法效率优于XML
适合用于SQL2000中想实现字符串拼接但是又不想函数的情况下.
5.TOP + ORDER BY 求中值
注意点:可以利用TOP + ORDER BY 巧妙解决取中值的问题,而且在SQL2000也可以方便使用
- SQL code
- --环境create table test_6(rq varchar(8), ddsj int)insert into test_6select'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',130go--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 ddsjfrom test_6 kgroup 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)<=1group by rq /*rq ddsj-------- -----------200805 35200806 200*/
在适用 缺点是没有合适的索引将会很慢
--6 OR 转变成AND
注意点:大家都知道OR在where条件出现时候,一般来说意味着索引的失效,只要筛选列上有一个没有索引的话.相比较而言,AND是有个索引就有个效果.所以我们有必要在能将OR转成AND的时候就转化.
- SQL code
- --环境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 100000insert 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--orselect *from test_7where col1<1 or (col1=1 and col2<3)--andselect *from test_7 where col1<=1 and (col1<1 and col2<3)
通过执行计划可以看到 带AND的开销比OR少了倍,它用到了COL1上的索引
--7 利用计算表达式改变IDENTITY
注意:使用select into 表的时候如果有自增列 会把自增的属性也复制过去,可以通过计算表达式去去除这个自增属性
- SQL code
- --环境create table test_8(id int identity(1,1),a int)insert test_8 select 1insert test_8 select 2insert test_8 select 3insert test_8 select 7insert test_8 select 9goselect ID+0 as id ,A into #1 from test_8 insert #1(a) select 8select * from #1 /*id A----------- -----------NULL 8 ---没有自增1 12 23 34 75 9*/
注意:在更新时也可以使用连续等于 @i=col=@i+1 <===> @i加后赋值给COL字段
- SQL code
- --环境CREATE TABLE test_9( id INT NOT NULL, col VARCHAR(5) NOT NULL);INSERT INTO test_9 VALUES(0, 'A');INSERT INTO test_9 VALUES(0, 'B');INSERT INTO test_9 VALUES(0, 'C');INSERT INTO test_9 VALUES(0, 'C');INSERT INTO test_9 VALUES(0, 'C');INSERT INTO test_9 VALUES(0, 'B');INSERT INTO test_9 VALUES(0, 'A');goDECLARE @i AS INT;SET @i = 0;UPDATE test_9 SET @i = id = @i + 1;goselect * from test_9 /*id col----------- -----1 A2 B3 C4 C5 C6 B7 A*/
- 【一些特别的地方和特别的解法】
- 【一些特别的地方和特别的解法】
- 【SQL SERVER中一些特别地方的特别解法2】
- SQL SERVER中一些特别地方的特别解法
- SQL SERVER中一些特别地方的特别解法
- SQL SERVER中一些特别地方的特别解法2
- UITextField 日常使用一些特别的地方
- java里的一些特别值得注意的地方
- 一些特别的SQL语法
- HTML一些特别的标签
- FMDB的一些特别使用
- Python一些特别的语法
- DIV居中特别注意的地方
- matplotlib安装(特别需要注意的地方)
- 特别特别繁忙的九月
- 重学C++Primer笔记5---一些基本语法需要特别注意的地方
- 关于C++的一些特别的站点
- NET 一些特别的错误解决
- Spring 简单介绍
- 74LS595
- python 利用win32com操作excel
- wo de tupian
- 论坛
- 【一些特别的地方和特别的解法】
- Linux下用C开发PHP扩展
- GCC-3.4.6源代码学习笔记(18)
- 窗口的子类化与超类化
- python DBUtils数据连接池与ms sql配合用法
- Studying note of GCC-3.4.6 source (18)
- 五种提高 SQL 性能的方法 1
- 修改ei.cfg,实现Windows 7旗舰版多版本选择
- 谷歌发布应用程序安全工具skipfish