﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;明月松间照 清泉石上流-文章分类-SQL</title><link>http://www.blogjava.net/xuechen0721/category/18011.html</link><description>&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;———&amp;nbsp;兵临城下&amp;nbsp;&amp;nbsp;猫科动物</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:14:28 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:14:28 GMT</pubDate><ttl>60</ttl><item><title>精妙的SQL语句</title><link>http://www.blogjava.net/xuechen0721/articles/84474.html</link><dc:creator>兵临城下</dc:creator><author>兵临城下</author><pubDate>Thu, 30 Nov 2006 01:10:00 GMT</pubDate><guid>http://www.blogjava.net/xuechen0721/articles/84474.html</guid><wfw:comment>http://www.blogjava.net/xuechen0721/comments/84474.html</wfw:comment><comments>http://www.blogjava.net/xuechen0721/articles/84474.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xuechen0721/comments/commentRss/84474.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xuechen0721/services/trackbacks/84474.html</trackback:ping><description><![CDATA[
		<div id="main">
				<div class="post">
						<h2>
								<a id="viewpost1_TitleUrl" href="/lbx19822004/archive/2006/11/30/84468.html">精妙的SQL语句</a> （转贴）</h2>                                 <font color="#ff3300"><strong>精妙的SQL语句<br /><br /></strong></font><font color="#000000">说明：复制表(只复制结构,源表名：a 新表名：b) <br /><br />SQL: select * into b from a where 1&lt;&gt;1 <br /><br />说明：拷贝表(拷贝数据,源表名：a 目标表名：b) <br /><br />SQL: insert into b(a, b, c) select d,e,f from b; <br /><br />说明：显示文章、提交人和最后回复时间 <br /><br />SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b <br /><br />说明：外连接查询(表名1：a 表名2：b) <br /><br />SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c <br /><br />说明：日程安排提前五分钟提醒 <br /><br />SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())&gt;5 <br /><br />说明：两张关联表，删除主表中已经在副表中没有的信息 <br /><br />SQL: <br /><br />delete from info where not exists ( select * from infobz where info.infid=infobz.infid ) <br /><br />说明：-- <br /><br />SQL: <br /><br />SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE <br /><br />FROM TABLE1, <br /><br />(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE <br /><br />FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND <br /><br />FROM TABLE2 <br /><br />WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X, <br /><br />(SELECT NUM, UPD_DATE, STOCK_ONHAND <br /><br />FROM TABLE2 <br /><br />WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = <br /><br />TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') ¦¦ '/01','YYYY/MM/DD') - 1, 'YYYY/MM') ) Y, <br /><br />WHERE X.NUM = Y.NUM （+） <br /><br />AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) &lt;&gt; X.STOCK_ONHAND ) B <br /><br />WHERE A.NUM = B.NUM <br /><br />说明：-- <br /><br />SQL: <br /><br />select * from studentinfo where not exists(select * from student where studentinfo.id=student.id) and 系名称='"&amp;strdepartmentname&amp;"' and 专业名称='"&amp;strprofessionname&amp;"' order by 性别,生源地,高考总成绩 <br /><br />说明： <br /><br />从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源） <br /><br />SQL: <br /><br />SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '01', a.factration)) AS JAN, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '02', a.factration)) AS FRI, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '03', a.factration)) AS MAR, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '04', a.factration)) AS APR, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '05', a.factration)) AS MAY, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '06', a.factration)) AS JUE, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '07', a.factration)) AS JUL, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '08', a.factration)) AS AGU, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '09', a.factration)) AS SEP, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '10', a.factration)) AS OCT, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '11', a.factration)) AS NOV, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '12', a.factration)) AS DEC <br /><br />FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration <br /><br />FROM TELFEESTAND a, TELFEE b <br /><br />WHERE a.tel = b.telfax) a <br /><br />GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') <br /><br />说明：四表联查问题： <br /><br />SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where ..... <br /><br />说明：得到表中最小的未使用的ID号 <br /><br />SQL: <br /><br />SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID <br /><br />FROM Handle <br /><br />WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)<br /><br /><br />--------------------------------------------------------------------------------<br /><br />1.说明：复制表(只复制结构,源表名：a 新表名：b) <br />SQL: select * into b from a where 1&lt;&gt;1 <br /><br />2.说明：拷贝表(拷贝数据,源表名：a 目标表名：b) <br /><br />SQL: insert into b(a, b, c) select d,e,f from a; <br /><br />3.说明：显示文章、提交人和最后回复时间 <br /><br />SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b <br /><br />4.说明：外连接查询(表名1：a 表名2：b) <br /><br />SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUTER JOIN b ON a.a = b.c <br /><br />5.说明：日程安排提前五分钟提醒 <br /><br />SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())&gt;5 <br /><br />6.说明：两张关联表，删除主表中已经在副表中没有的信息 <br /><br />SQL: <br /><br />delete from info where not exists ( select * from infobz where info.infid=infobz.infid ) <br /><br />说明：-- <br /><br />SQL: <br /><br />SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE <br /><br />FROM TABLE1, <br /><br />(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE <br /><br />FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND <br /><br />FROM TABLE2 <br /><br />WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X, <br /><br />(SELECT NUM, UPD_DATE, STOCK_ONHAND <br /><br />FROM TABLE2 <br /><br />WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = <br /><br />TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') || '/01','YYYY/MM/DD') - 1, 'YYYY/MM') ) Y, <br /><br />WHERE X.NUM = Y.NUM （+） <br /><br />AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) &lt;&gt; X.STOCK_ONHAND ) B <br /><br />WHERE A.NUM = B.NUM <br /><br />说明：-- <br /><br />SQL: <br /><br />select * from studentinfo where not exists(select * from student where studentinfo.id=student.id) and 系名称='"&amp;strdepartmentname&amp;"' and 专业名称='"&amp;strprofessionname&amp;"' order by 性别,生源地,高考总成绩 <br /><br />7.说明： <br /><br />从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源） <br /><br />SQL: <br /><br />SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '01', a.factration)) AS JAN, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '02', a.factration)) AS FRI, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '03', a.factration)) AS MAR, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '04', a.factration)) AS APR, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '05', a.factration)) AS MAY, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '06', a.factration)) AS JUE, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '07', a.factration)) AS JUL, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '08', a.factration)) AS AGU, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '09', a.factration)) AS SEP, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '10', a.factration)) AS OCT, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '11', a.factration)) AS NOV, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '12', a.factration)) AS DEC <br /><br />FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration <br /><br />FROM TELFEESTAND a, TELFEE b <br /><br />WHERE a.tel = b.telfax) a <br /><br />GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') <br /><br />8.说明：四表联查问题： <br /><br />SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where ..... <br /><br />9.说明：得到表中最小的未使用的ID号 <br /><br />SQL: <br /><br />SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID <br /><br />FROM Handle <br /><br />WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)<br /><br /><br /><br />9.SQL语句技巧<br />9.1、一个SQL语句的问题:行列转换<br />select * from v_temp<br />上面的视图结果如下:<br />user_name role_name<br />-------------------------<br />系统管理员 管理员 <br />feng 管理员 <br />feng 一般用户 <br />test 一般用户 <br />想把结果变成这样:<br />user_name role_name<br />---------------------------<br />系统管理员 管理员 <br />feng 管理员,一般用户 <br />test 一般用户<br />===================<br />create table a_test(name varchar(20),role2 varchar(20))<br />insert into a_test values('李','管理員')<br />insert into a_test values('張','管理員')<br />insert into a_test values('張','一般用戶')<br />insert into a_test values('常','一般用戶')<br /><br />create function join_str(@content varchar(100))<br />returns varchar(2000)<br />as<br />begin<br />declare @str varchar(2000)<br />set @str='<br />select @str=@str+','+rtrim(role2) from a_test where [name]=@content<br />select @str=right(@str,len(@str)-1)<br />return @str<br />end<br />go<br /><br />--调用：<br />select [name],dbo.join_str([name]) role2 from a_test group by [name]<br /><br />--select distinct name,dbo.uf_test(name) from a_test<br /><br />9.2、求助！快速比较结构相同的两表<br />结构相同的两表，一表有记录3万条左右，一表有记录2万条左右，我怎样快速查找两表的不同记录？<br />============================<br />给你一个测试方法，从northwind中的orders表取数据。<br />select * into n1 from orders<br />select * into n2 from orders<br /><br />select * from n1<br />select * from n2<br /><br />--添加主键，然后修改n1中若干字段的若干条<br />alter table n1 add constraint pk_n1_id primary key (OrderID)<br />alter table n2 add constraint pk_n2_id primary key (OrderID)<br /><br />select OrderID from (select * from n1<br />union <br />select * from n2) a group by OrderID having count(*) &gt; 1<br /><br />应该可以，而且将不同的记录的ID显示出来。<br />下面的适用于双方记录一样的情况，<br /><br />select * from n1 where orderid in<br />(<br />select OrderID from (select * from n1<br />union <br />select * from n2) a group by OrderID having count(*) &gt; 1<br />) <br />至于双方互不存在的记录是比较好处理的<br />--删除n1,n2中若干条记录<br />delete from n1 where orderID in ('10728','10730')<br />delete from n2 where orderID in ('11000','11001')<br /><br />--*************************************************************<br />-- 双方都有该记录却不完全相同<br />select * from n1 where orderid in<br />(<br />select OrderID from (select * from n1<br />union <br />select * from n2) a group by OrderID having count(*) &gt; 1<br />)<br />union<br />--n2中存在但在n1中不存的在10728,10730<br />select * from n1 where OrderID not in (select OrderID from n2)<br />union<br />--n1中存在但在n2中不存的在11000,11001<br />select * from n2 where OrderID not in (select OrderID from n1)<br /><br />9.3、四种方法取表里n到m条纪录：<br /><br />1.<br />select top m * into 临时表(或表变量) from tablename order by columnname -- 将top m笔插入<br />set rowcount n<br />select * from 表变量 order by columnname desc<br /><br /><br />2.<br />select top n * from <br />(select top m * from tablename order by columnname) a<br />order by columnname desc<br /><br /><br />3.如果tablename里没有其他identity列，那么：<br />select identity(int) id0,* into #temp from tablename<br /><br />取n到m条的语句为：<br />select * from #temp where id0 &gt;=n and id0 &lt;= m<br /><br />如果你在执行select identity(int) id0,* into #temp from tablename这条语句的时候报错,那是因为你的DB中间的select into/bulkcopy属性没有打开要先执行：<br />exec sp_dboption 你的DB名字,'select into/bulkcopy',true<br /><br /><br />4.如果表里有identity属性，那么简单：<br />select * from tablename where identitycol between n and m <br />5.如何删除一个表中重复的记录？<br />create table a_dist(id int,name varchar(20))<br /><br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br /><br />exec up_distinct 'a_dist','id'<br /><br />select * from a_dist<br /><br />create procedure up_distinct(@t_name varchar(30),@f_key varchar(30))<br />--f_key表示是分組字段﹐即主鍵字段<br />as<br />begin<br />declare @max integer,@id varchar(30) ,@sql varchar(7999) ,@type integer<br />select @sql = 'declare cur_rows cursor for select '+@f_key+' ,count(*) from ' +@t_name +' group by ' +@f_key +' having count(*) &gt; 1'<br />exec(@sql)<br />open cur_rows <br />fetch cur_rows into @id,@max <br />while @@fetch_status=0 <br />begin <br />select @max = @max -1 <br />set rowcount @max <br />select @type = xtype from syscolumns where id=object_id(@t_name) and name=@f_key<br />if @type=56<br />select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+ @id <br />if @type=167<br />select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+''+ @id +'' <br />exec(@sql)<br />fetch cur_rows into @id,@max <br />end <br />close cur_rows <br />deallocate cur_rows<br />set rowcount 0<br />end<br /><br />select * from systypes<br />select * from syscolumns where id = object_id('a_dist')<br /><br />9.4.查询数据的最大排序问题（只能用一条语句写） <br />CREATE TABLE hard (qu char (11) ,co char (11) ,je numeric(3, 0)) <br /><br />insert into hard values ('A','1',3)<br />insert into hard values ('A','2',4)<br />insert into hard values ('A','4',2)<br />insert into hard values ('A','6',9)<br />insert into hard values ('B','1',4)<br />insert into hard values ('B','2',5)<br />insert into hard values ('B','3',6)<br />insert into hard values ('C','3',4)<br />insert into hard values ('C','6',7)<br />insert into hard values ('C','2',3)<br /><br /><br />要求查询出来的结果如下：<br /><br />qu co je <br />----------- ----------- ----- <br />A 6 9<br />A 2 4<br />B 3 6<br />B 2 5<br />C 6 7<br />C 3 4<br /><br /><br />就是要按qu分组，每组中取je最大的前2位！！<br />而且只能用一句sql语句！！！<br />select * from hard a where je in (select top 2 je from hard b where a.qu=b.qu order by je) <br />9.5.求删除重复记录的sql语句？ <br />怎样把具有相同字段的纪录删除，只留下一条。<br />例如，表test里有id,name字段<br />如果有name相同的记录 只留下一条，其余的删除。<br />name的内容不定，相同的记录数不定。<br />有没有这样的sql语句？<br />==============================<br />A:一个完整的解决方案：<br /><br />将重复的记录记入temp1表:<br />select [标志字段id],count(*) into temp1 from [表名]<br />group by [标志字段id]<br />having count(*)&gt;1<br /><br />2、将不重复的记录记入temp1表:<br />insert temp1<br />select [标志字段id],count(*) from [表名]<br />group by [标志字段id]<br />having count(*)=1<br /><br />3、作一个包含所有不重复记录的表：<br />select * into temp2 from [表名]<br />where 标志字段id in(select 标志字段id from temp1)<br /><br />4、删除重复表:<br />delete [表名]<br /><br />5、恢复表：<br />insert [表名]<br />select * from temp2<br /><br />6、删除临时表:<br />drop table temp1<br />drop table temp2<br />================================<br />B:<br />create table a_dist(id int,name varchar(20))<br /><br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br /><br />exec up_distinct 'a_dist','id'<br /><br />select * from a_dist<br /><br />create procedure up_distinct(@t_name varchar(30),@f_key varchar(30))<br />--f_key表示是分組字段﹐即主鍵字段<br />as<br />begin<br />declare @max integer,@id varchar(30) ,@sql varchar(7999) ,@type integer<br />select @sql = 'declare cur_rows cursor for select '+@f_key+' ,count(*) from ' +@t_name +' group by ' +@f_key +' having count(*) &gt; 1'<br />exec(@sql)<br />open cur_rows <br />fetch cur_rows into @id,@max <br />while @@fetch_status=0 <br />begin <br />select @max = @max -1 <br />set rowcount @max <br />select @type = xtype from syscolumns where id=object_id(@t_name) and name=@f_key<br />if @type=56<br />select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+ @id <br />if @type=167<br />select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+''+ @id +'' <br />exec(@sql)<br />fetch cur_rows into @id,@max <br />end <br />close cur_rows <br />deallocate cur_rows<br />set rowcount 0<br />end<br /><br />select * from systypes<br />select * from syscolumns where id = object_id('a_dist')<br /><br />10.1. 行列转换--普通 <br /><br />假设有张学生成绩表(CJ)如下 <br />Name Subject Result <br />张三 语文 80 <br />张三 数学 90 <br />张三 物理 85 <br />李四 语文 85 <br />李四 数学 92 <br />李四 物理 82 <br /><br />想变成 <br />姓名 语文 数学 物理 <br />张三 80 90 85 <br />李四 85 92 82 <br /><br />declare @sql varchar(4000) <br />set @sql = 'select Name' <br />select @sql = @sql + ',sum(case Subject when ''+Subject+'' then Result end) ['+Subject+']' <br />from (select distinct Subject from CJ) as a <br />select @sql = @sql+' from test group by name' <br />exec(@sql) <br /><br />10.2. 行列转换--合并 <br /><br />有表A, <br />id pid <br />1 1 <br />1 2 <br />1 3 <br />2 1 <br />2 2 <br />3 1 <br />如何化成表B: <br />id pid <br />1 1,2,3 <br />2 1,2 <br />3 1 <br /><br />创建一个合并的函数 <br />create function fmerg(@id int) <br />returns varchar(8000) <br />as <br />begin <br />declare @str varchar(8000) <br />set @str=' <br />select @str=@str+','+cast(pid as varchar) from 表A where id=@id <br />set @str=right(@str,len(@str)-1) <br />return(@str) <br />End <br />go <br /><br />--调用自定义函数得到结果 <br />select distinct id,dbo.fmerg(id) from 表A <br /><br />10.3. 如何取得一个数据表的所有列名 <br /><br />方法如下：先从SYSTEMOBJECT系统表中取得数据表的SYSTEMID,然后再SYSCOLUMN表中取得该数据表的所有列名。 <br />SQL语句如下： <br />declare @objid int,@objname char(40) <br />set @objname = 'tablename' <br />select @objid = id from sysobjects where id = object_id(@objname) <br />select 'Column_name' = name from syscolumns where id = @objid order by colid <br /><br />是不是太简单了？ 呵呵 不过经常用阿. <br /><br />10.4. 通过SQL语句来更改用户的密码 <br /><br />修改别人的,需要sysadmin role <br />EXEC sp_password NULL, 'newpassword', 'User' <br /><br />如果帐号为SA执行EXEC sp_password NULL, 'newpassword', sa <br /><br />10.5. 怎么判断出一个表的哪些字段不允许为空？ <br /><br />select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where IS_NULLABLE='NO' and TABLE_NAME=tablename <br /><br />10.6. 如何在数据库里找到含有相同字段的表？ <br />a. 查已知列名的情况 <br />SELECT b.name as TableName,a.name as columnname <br />From syscolumns a INNER JOIN sysobjects b <br />ON a.id=b.id <br />AND b.type='U' <br />AND a.name='你的字段名字' <br /><br />b. 未知列名查所有在不同表出现过的列名 <br />Select o.name As tablename,s1.name As columnname <br />From syscolumns s1, sysobjects o <br />Where s1.id = o.id <br />And o.type = 'U' <br />And Exists ( <br />Select 1 From syscolumns s2 <br />Where s1.name = s2.name <br />And s1.id &lt;&gt; s2.id <br />) <br /><br />10.7. 查询第xxx行数据 <br /><br />假设id是主键： <br />select * <br />from (select top xxx * from yourtable) aa <br />where not exists(select 1 from (select top xxx-1 * from yourtable) bb where aa.id=bb.id) <br /><br />如果使用游标也是可以的 <br />fetch absolute [number] from [cursor_name] <br />行数为绝对行数 <br /><br />10.8. SQL Server日期计算 <br />a. 一个月的第一天 <br />SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0) <br />b. 本周的星期一 <br />SELECT DATEADD(wk, DATEDIFF(wk,0,getdate()), 0) <br />c. 一年的第一天 <br />SELECT DATEADD(yy, DATEDIFF(yy,0,getdate()), 0) <br />d. 季度的第一天 <br />SELECT DATEADD(qq, DATEDIFF(qq,0,getdate()), 0) <br />e. 上个月的最后一天 <br />SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)) <br />f. 去年的最后一天 <br />SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)) <br />g. 本月的最后一天 <br />SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0)) <br />h. 本月的第一个星期一 <br />select DATEADD(wk, DATEDIFF(wk,0, <br />dateadd(dd,6-datepart(day,getdate()),getdate()) <br />), 0) <br />i. 本年的最后一天 <br />SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))。 <br /><br />11.1.获取表结构[把 'sysobjects' 替换 成 'tablename' 即可] <br /><br />SELECT CASE IsNull(I.name, ') <br />When ' Then ' <br />Else '*' <br />End as IsPK, <br />Object_Name(A.id) as t_name, <br />A.name as c_name, <br />IsNull(SubString(M.text, 1, 254), ') as pbc_init, <br />T.name as F_DataType, <br />CASE IsNull(TYPEPROPERTY(T.name, 'Scale'), ') <br />WHEN ' Then Cast(A.prec as varchar) <br />ELSE Cast(A.prec as varchar) + ',' + Cast(A.scale as varchar) <br />END as F_Scale, <br />A.isnullable as F_isNullAble <br />FROM Syscolumns as A <br />JOIN Systypes as T <br />ON (A.xType = T.xUserType AND A.Id = Object_id('sysobjects') ) <br />LEFT JOIN ( SysIndexes as I <br />JOIN Syscolumns as A1 <br />ON ( I.id = A1.id and A1.id = object_id('sysobjects') and (I.status &amp; 0x800) = 0x800 AND A1.colid &lt;= I.keycnt) ) <br />ON ( A.id = I.id AND A.name = index_col('sysobjects', I.indid, A1.colid) ) <br />LEFT JOIN SysComments as M <br />ON ( M.id = A.cdefault and ObjectProperty(A.cdefault, 'IsConstraint') = 1 ) <br />ORDER BY A.Colid ASC <br /><br /><br />11.2..提取数据库内所有表的字段详细说明的SQL语句 <br /><br />SELECT <br />(case when a.colorder=1 then d.name else ' end) N'表名', <br />a.colorder N'字段序号', <br />a.name N'字段名', <br />(case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then '√'else ' <br />end) N'标识', <br />(case when (SELECT count(*) <br />FROM sysobjects <br />WHERE (name in <br />(SELECT name <br />FROM sysindexes <br />WHERE (id = a.id) AND (indid in <br />(SELECT indid <br />FROM sysindexkeys <br />WHERE (id = a.id) AND (colid in <br />(SELECT colid <br />FROM syscolumns <br />WHERE (id = a.id) AND (name = a.name))))))) AND <br />(xtype = 'PK'))&gt;0 then '√' else ' end) N'主键', <br />b.name N'类型', <br />a.length N'占用字节数', <br />COLUMNPROPERTY(a.id,a.name,'PRECISION') as N'长度', <br />isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0) as N'小数位数', <br />(case when a.isnullable=1 then '√'else ' end) N'允许空', <br />isnull(e.text,') N'默认值', <br />isnull(g.[value],') AS N'字段说明' <br />FROM syscolumns a <br />left join systypes b <br />on a.xtype=b.xusertype <br />inner join sysobjects d <br />on a.id=d.id and d.xtype='U' and d.name&lt;&gt;'dtproperties' <br />left join syscomments e <br />on a.cdefault=e.id <br />left join sysproperties g <br />on a.id=g.id AND a.colid = g.smallid <br />order by object_name(a.id),a.colorder <br /><br />11.3.快速获取表test的记录总数[对大容量表非常有效] <br /><br />快速获取表test的记录总数: <br />select rows from sysindexes where id = object_id(‘test’) and indid in (0,1)<br /><br />update 2 set KHXH=(ID+1)\2 2行递增编号<br />update [23] set id1 = 'No.'+right('00000000'+id,6) where id not like 'No%' //递增<br />update [23] set id1= 'No.'+right('00000000'+replace(id1,'No.','),6) //补位递增<br />delete from [1] where (id%2)=1 <br />奇数<br /><br />替换表名字段<br />update [1] set domurl = replace(domurl,'Upload/Imgswf/','Upload/Photo/') where domurl like '%Upload/Imgswf/%'<br /><br />截位<br />SELECT LEFT(表名, 5)说明：复制表(只复制结构,源表名：a 新表名：b) <br /><br />SQL: select * into b from a where 1&lt;&gt;1 <br /><br />说明：拷贝表(拷贝数据,源表名：a 目标表名：b) <br /><br />SQL: insert into b(a, b, c) select d,e,f from b; <br /><br />说明：显示文章、提交人和最后回复时间 <br /><br />SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b <br /><br />说明：外连接查询(表名1：a 表名2：b) <br /><br />SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c <br /><br />说明：日程安排提前五分钟提醒 <br /><br />SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())&gt;5 <br /><br />说明：两张关联表，删除主表中已经在副表中没有的信息 <br /><br />SQL: <br /><br />delete from info where not exists ( select * from infobz where info.infid=infobz.infid ) <br /><br />说明：-- <br /><br />SQL: <br /><br />SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE <br /><br />FROM TABLE1, <br /><br />(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE <br /><br />FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND <br /><br />FROM TABLE2 <br /><br />WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X, <br /><br />(SELECT NUM, UPD_DATE, STOCK_ONHAND <br /><br />FROM TABLE2 <br /><br />WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = <br /><br />TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') ¦¦ '/01','YYYY/MM/DD') - 1, 'YYYY/MM') ) Y, <br /><br />WHERE X.NUM = Y.NUM （+） <br /><br />AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) &lt;&gt; X.STOCK_ONHAND ) B <br /><br />WHERE A.NUM = B.NUM <br /><br />说明：-- <br /><br />SQL: <br /><br />select * from studentinfo where not exists(select * from student where studentinfo.id=student.id) and 系名称='"&amp;strdepartmentname&amp;"' and 专业名称='"&amp;strprofessionname&amp;"' order by 性别,生源地,高考总成绩 <br /><br />说明： <br /><br />从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源） <br /><br />SQL: <br /><br />SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '01', a.factration)) AS JAN, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '02', a.factration)) AS FRI, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '03', a.factration)) AS MAR, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '04', a.factration)) AS APR, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '05', a.factration)) AS MAY, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '06', a.factration)) AS JUE, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '07', a.factration)) AS JUL, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '08', a.factration)) AS AGU, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '09', a.factration)) AS SEP, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '10', a.factration)) AS OCT, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '11', a.factration)) AS NOV, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '12', a.factration)) AS DEC <br /><br />FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration <br /><br />FROM TELFEESTAND a, TELFEE b <br /><br />WHERE a.tel = b.telfax) a <br /><br />GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') <br /><br />说明：四表联查问题： <br /><br />SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where ..... <br /><br />说明：得到表中最小的未使用的ID号 <br /><br />SQL: <br /><br />SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID <br /><br />FROM Handle <br /><br />WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)<br /><br /><br />--------------------------------------------------------------------------------<br /><br />1.说明：复制表(只复制结构,源表名：a 新表名：b) <br />SQL: select * into b from a where 1&lt;&gt;1 <br /><br />2.说明：拷贝表(拷贝数据,源表名：a 目标表名：b) <br /><br />SQL: insert into b(a, b, c) select d,e,f from a; <br /><br />3.说明：显示文章、提交人和最后回复时间 <br /><br />SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b <br /><br />4.说明：外连接查询(表名1：a 表名2：b) <br /><br />SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUTER JOIN b ON a.a = b.c <br /><br />5.说明：日程安排提前五分钟提醒 <br /><br />SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())&gt;5 <br /><br />6.说明：两张关联表，删除主表中已经在副表中没有的信息 <br /><br />SQL: <br /><br />delete from info where not exists ( select * from infobz where info.infid=infobz.infid ) <br /><br />说明：-- <br /><br />SQL: <br /><br />SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE <br /><br />FROM TABLE1, <br /><br />(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE <br /><br />FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND <br /><br />FROM TABLE2 <br /><br />WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X, <br /><br />(SELECT NUM, UPD_DATE, STOCK_ONHAND <br /><br />FROM TABLE2 <br /><br />WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = <br /><br />TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') || '/01','YYYY/MM/DD') - 1, 'YYYY/MM') ) Y, <br /><br />WHERE X.NUM = Y.NUM （+） <br /><br />AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) &lt;&gt; X.STOCK_ONHAND ) B <br /><br />WHERE A.NUM = B.NUM <br /><br />说明：-- <br /><br />SQL: <br /><br />select * from studentinfo where not exists(select * from student where studentinfo.id=student.id) and 系名称='"&amp;strdepartmentname&amp;"' and 专业名称='"&amp;strprofessionname&amp;"' order by 性别,生源地,高考总成绩 <br /><br />7.说明： <br /><br />从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源） <br /><br />SQL: <br /><br />SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '01', a.factration)) AS JAN, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '02', a.factration)) AS FRI, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '03', a.factration)) AS MAR, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '04', a.factration)) AS APR, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '05', a.factration)) AS MAY, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '06', a.factration)) AS JUE, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '07', a.factration)) AS JUL, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '08', a.factration)) AS AGU, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '09', a.factration)) AS SEP, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '10', a.factration)) AS OCT, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '11', a.factration)) AS NOV, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '12', a.factration)) AS DEC <br /><br />FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration <br /><br />FROM TELFEESTAND a, TELFEE b <br /><br />WHERE a.tel = b.telfax) a <br /><br />GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') <br /><br />8.说明：四表联查问题： <br /><br />SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where ..... <br /><br />9.说明：得到表中最小的未使用的ID号 <br /><br />SQL: <br /><br />SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID <br /><br />FROM Handle <br /><br />WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)<br /><br /><br /><br />9.SQL语句技巧<br />9.1、一个SQL语句的问题:行列转换<br />select * from v_temp<br />上面的视图结果如下:<br />user_name role_name<br />-------------------------<br />系统管理员 管理员 <br />feng 管理员 <br />feng 一般用户 <br />test 一般用户 <br />想把结果变成这样:<br />user_name role_name<br />---------------------------<br />系统管理员 管理员 <br />feng 管理员,一般用户 <br />test 一般用户<br />===================<br />create table a_test(name varchar(20),role2 varchar(20))<br />insert into a_test values('李','管理員')<br />insert into a_test values('張','管理員')<br />insert into a_test values('張','一般用戶')<br />insert into a_test values('常','一般用戶')<br /><br />create function join_str(@content varchar(100))<br />returns varchar(2000)<br />as<br />begin<br />declare @str varchar(2000)<br />set @str='<br />select @str=@str+','+rtrim(role2) from a_test where [name]=@content<br />select @str=right(@str,len(@str)-1)<br />return @str<br />end<br />go<br /><br />--调用：<br />select [name],dbo.join_str([name]) role2 from a_test group by [name]<br /><br />--select distinct name,dbo.uf_test(name) from a_test<br /><br />9.2、求助！快速比较结构相同的两表<br />结构相同的两表，一表有记录3万条左右，一表有记录2万条左右，我怎样快速查找两表的不同记录？<br />============================<br />给你一个测试方法，从northwind中的orders表取数据。<br />select * into n1 from orders<br />select * into n2 from orders<br /><br />select * from n1<br />select * from n2<br /><br />--添加主键，然后修改n1中若干字段的若干条<br />alter table n1 add constraint pk_n1_id primary key (OrderID)<br />alter table n2 add constraint pk_n2_id primary key (OrderID)<br /><br />select OrderID from (select * from n1<br />union <br />select * from n2) a group by OrderID having count(*) &gt; 1<br /><br />应该可以，而且将不同的记录的ID显示出来。<br />下面的适用于双方记录一样的情况，<br /><br />select * from n1 where orderid in<br />(<br />select OrderID from (select * from n1<br />union <br />select * from n2) a group by OrderID having count(*) &gt; 1<br />) <br />至于双方互不存在的记录是比较好处理的<br />--删除n1,n2中若干条记录<br />delete from n1 where orderID in ('10728','10730')<br />delete from n2 where orderID in ('11000','11001')<br /><br />--*************************************************************<br />-- 双方都有该记录却不完全相同<br />select * from n1 where orderid in<br />(<br />select OrderID from (select * from n1<br />union <br />select * from n2) a group by OrderID having count(*) &gt; 1<br />)<br />union<br />--n2中存在但在n1中不存的在10728,10730<br />select * from n1 where OrderID not in (select OrderID from n2)<br />union<br />--n1中存在但在n2中不存的在11000,11001<br />select * from n2 where OrderID not in (select OrderID from n1)<br /><br />9.3、四种方法取表里n到m条纪录：<br /><br />1.<br />select top m * into 临时表(或表变量) from tablename order by columnname -- 将top m笔插入<br />set rowcount n<br />select * from 表变量 order by columnname desc<br /><br /><br />2.<br />select top n * from <br />(select top m * from tablename order by columnname) a<br />order by columnname desc<br /><br /><br />3.如果tablename里没有其他identity列，那么：<br />select identity(int) id0,* into #temp from tablename<br /><br />取n到m条的语句为：<br />select * from #temp where id0 &gt;=n and id0 &lt;= m<br /><br />如果你在执行select identity(int) id0,* into #temp from tablename这条语句的时候报错,那是因为你的DB中间的select into/bulkcopy属性没有打开要先执行：<br />exec sp_dboption 你的DB名字,'select into/bulkcopy',true<br /><br /><br />4.如果表里有identity属性，那么简单：<br />select * from tablename where identitycol between n and m <br />5.如何删除一个表中重复的记录？<br />create table a_dist(id int,name varchar(20))<br /><br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br /><br />exec up_distinct 'a_dist','id'<br /><br />select * from a_dist<br /><br />create procedure up_distinct(@t_name varchar(30),@f_key varchar(30))<br />--f_key表示是分組字段﹐即主鍵字段<br />as<br />begin<br />declare @max integer,@id varchar(30) ,@sql varchar(7999) ,@type integer<br />select @sql = 'declare cur_rows cursor for select '+@f_key+' ,count(*) from ' +@t_name +' group by ' +@f_key +' having count(*) &gt; 1'<br />exec(@sql)<br />open cur_rows <br />fetch cur_rows into @id,@max <br />while @@fetch_status=0 <br />begin <br />select @max = @max -1 <br />set rowcount @max <br />select @type = xtype from syscolumns where id=object_id(@t_name) and name=@f_key<br />if @type=56<br />select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+ @id <br />if @type=167<br />select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+''+ @id +'' <br />exec(@sql)<br />fetch cur_rows into @id,@max <br />end <br />close cur_rows <br />deallocate cur_rows<br />set rowcount 0<br />end<br /><br />select * from systypes<br />select * from syscolumns where id = object_id('a_dist')<br /><br />9.4.查询数据的最大排序问题（只能用一条语句写） <br />CREATE TABLE hard (qu char (11) ,co char (11) ,je numeric(3, 0)) <br /><br />insert into hard values ('A','1',3)<br />insert into hard values ('A','2',4)<br />insert into hard values ('A','4',2)<br />insert into hard values ('A','6',9)<br />insert into hard values ('B','1',4)<br />insert into hard values ('B','2',5)<br />insert into hard values ('B','3',6)<br />insert into hard values ('C','3',4)<br />insert into hard values ('C','6',7)<br />insert into hard values ('C','2',3)<br /><br /><br />要求查询出来的结果如下：<br /><br />qu co je <br />----------- ----------- ----- <br />A 6 9<br />A 2 4<br />B 3 6<br />B 2 5<br />C 6 7<br />C 3 4<br /><br /><br />就是要按qu分组，每组中取je最大的前2位！！<br />而且只能用一句sql语句！！！<br />select * from hard a where je in (select top 2 je from hard b where a.qu=b.qu order by je) <br />9.5.求删除重复记录的sql语句？ <br />怎样把具有相同字段的纪录删除，只留下一条。<br />例如，表test里有id,name字段<br />如果有name相同的记录 只留下一条，其余的删除。<br />name的内容不定，相同的记录数不定。<br />有没有这样的sql语句？<br />==============================<br />A:一个完整的解决方案：<br /><br />将重复的记录记入temp1表:<br />select [标志字段id],count(*) into temp1 from [表名]<br />group by [标志字段id]<br />having count(*)&gt;1<br /><br />2、将不重复的记录记入temp1表:<br />insert temp1<br />select [标志字段id],count(*) from [表名]<br />group by [标志字段id]<br />having count(*)=1<br /><br />3、作一个包含所有不重复记录的表：<br />select * into temp2 from [表名]<br />where 标志字段id in(select 标志字段id from temp1)<br /><br />4、删除重复表:<br />delete [表名]<br /><br />5、恢复表：<br />insert [表名]<br />select * from temp2<br /><br />6、删除临时表:<br />drop table temp1<br />drop table temp2<br />================================<br />B:<br />create table a_dist(id int,name varchar(20))<br /><br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br />insert into a_dist values(1,'abc')<br /><br />exec up_distinct 'a_dist','id'<br /><br />select * from a_dist<br /><br />create procedure up_distinct(@t_name varchar(30),@f_key varchar(30))<br />--f_key表示是分組字段﹐即主鍵字段<br />as<br />begin<br />declare @max integer,@id varchar(30) ,@sql varchar(7999) ,@type integer<br />select @sql = 'declare cur_rows cursor for select '+@f_key+' ,count(*) from ' +@t_name +' group by ' +@f_key +' having count(*) &gt; 1'<br />exec(@sql)<br />open cur_rows <br />fetch cur_rows into @id,@max <br />while @@fetch_status=0 <br />begin <br />select @max = @max -1 <br />set rowcount @max <br />select @type = xtype from syscolumns where id=object_id(@t_name) and name=@f_key<br />if @type=56<br />select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+ @id <br />if @type=167<br />select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+''+ @id +'' <br />exec(@sql)<br />fetch cur_rows into @id,@max <br />end <br />close cur_rows <br />deallocate cur_rows<br />set rowcount 0<br />end<br /><br />select * from systypes<br />select * from syscolumns where id = object_id('a_dist')<br /><br />10.1. 行列转换--普通 <br /><br />假设有张学生成绩表(CJ)如下 <br />Name Subject Result <br />张三 语文 80 <br />张三 数学 90 <br />张三 物理 85 <br />李四 语文 85 <br />李四 数学 92 <br />李四 物理 82 <br /><br />想变成 <br />姓名 语文 数学 物理 <br />张三 80 90 85 <br />李四 85 92 82 <br /><br />declare @sql varchar(4000) <br />set @sql = 'select Name' <br />select @sql = @sql + ',sum(case Subject when ''+Subject+'' then Result end) ['+Subject+']' <br />from (select distinct Subject from CJ) as a <br />select @sql = @sql+' from test group by name' <br />exec(@sql) <br /><br />10.2. 行列转换--合并 <br /><br />有表A, <br />id pid <br />1 1 <br />1 2 <br />1 3 <br />2 1 <br />2 2 <br />3 1 <br />如何化成表B: <br />id pid <br />1 1,2,3 <br />2 1,2 <br />3 1 <br /><br />创建一个合并的函数 <br />create function fmerg(@id int) <br />returns varchar(8000) <br />as <br />begin <br />declare @str varchar(8000) <br />set @str=' <br />select @str=@str+','+cast(pid as varchar) from 表A where id=@id <br />set @str=right(@str,len(@str)-1) <br />return(@str) <br />End <br />go <br /><br />--调用自定义函数得到结果 <br />select distinct id,dbo.fmerg(id) from 表A <br /><br />10.3. 如何取得一个数据表的所有列名 <br /><br />方法如下：先从SYSTEMOBJECT系统表中取得数据表的SYSTEMID,然后再SYSCOLUMN表中取得该数据表的所有列名。 <br />SQL语句如下： <br />declare @objid int,@objname char(40) <br />set @objname = 'tablename' <br />select @objid = id from sysobjects where id = object_id(@objname) <br />select 'Column_name' = name from syscolumns where id = @objid order by colid <br /><br />是不是太简单了？ 呵呵 不过经常用阿. <br /><br />10.4. 通过SQL语句来更改用户的密码 <br /><br />修改别人的,需要sysadmin role <br />EXEC sp_password NULL, 'newpassword', 'User' <br /><br />如果帐号为SA执行EXEC sp_password NULL, 'newpassword', sa <br /><br />10.5. 怎么判断出一个表的哪些字段不允许为空？ <br /><br />select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where IS_NULLABLE='NO' and TABLE_NAME=tablename <br /><br />10.6. 如何在数据库里找到含有相同字段的表？ <br />a. 查已知列名的情况 <br />SELECT b.name as TableName,a.name as columnname <br />From syscolumns a INNER JOIN sysobjects b <br />ON a.id=b.id <br />AND b.type='U' <br />AND a.name='你的字段名字' <br /><br />b. 未知列名查所有在不同表出现过的列名 <br />Select o.name As tablename,s1.name As columnname <br />From syscolumns s1, sysobjects o <br />Where s1.id = o.id <br />And o.type = 'U' <br />And Exists ( <br />Select 1 From syscolumns s2 <br />Where s1.name = s2.name <br />And s1.id &lt;&gt; s2.id <br />) <br /><br />10.7. 查询第xxx行数据 <br /><br />假设id是主键： <br />select * <br />from (select top xxx * from yourtable) aa <br />where not exists(select 1 from (select top xxx-1 * from yourtable) bb where aa.id=bb.id) <br /><br />如果使用游标也是可以的 <br />fetch absolute [number] from [cursor_name] <br />行数为绝对行数 <br /><br />10.8. SQL Server日期计算 <br />a. 一个月的第一天 <br />SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0) <br />b. 本周的星期一 <br />SELECT DATEADD(wk, DATEDIFF(wk,0,getdate()), 0) <br />c. 一年的第一天 <br />SELECT DATEADD(yy, DATEDIFF(yy,0,getdate()), 0) <br />d. 季度的第一天 <br />SELECT DATEADD(qq, DATEDIFF(qq,0,getdate()), 0) <br />e. 上个月的最后一天 <br />SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)) <br />f. 去年的最后一天 <br />SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)) <br />g. 本月的最后一天 <br />SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0)) <br />h. 本月的第一个星期一 <br />select DATEADD(wk, DATEDIFF(wk,0, <br />dateadd(dd,6-datepart(day,getdate()),getdate()) <br />), 0) <br />i. 本年的最后一天 <br />SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))。 <br /><br />11.1.获取表结构[把 'sysobjects' 替换 成 'tablename' 即可] <br /><br />SELECT CASE IsNull(I.name, ') <br />When ' Then ' <br />Else '*' <br />End as IsPK, <br />Object_Name(A.id) as t_name, <br />A.name as c_name, <br />IsNull(SubString(M.text, 1, 254), ') as pbc_init, <br />T.name as F_DataType, <br />CASE IsNull(TYPEPROPERTY(T.name, 'Scale'), ') <br />WHEN ' Then Cast(A.prec as varchar) <br />ELSE Cast(A.prec as varchar) + ',' + Cast(A.scale as varchar) <br />END as F_Scale, <br />A.isnullable as F_isNullAble <br />FROM Syscolumns as A <br />JOIN Systypes as T <br />ON (A.xType = T.xUserType AND A.Id = Object_id('sysobjects') ) <br />LEFT JOIN ( SysIndexes as I <br />JOIN Syscolumns as A1 <br />ON ( I.id = A1.id and A1.id = object_id('sysobjects') and (I.status &amp; 0x800) = 0x800 AND A1.colid &lt;= I.keycnt) ) <br />ON ( A.id = I.id AND A.name = index_col('sysobjects', I.indid, A1.colid) ) <br />LEFT JOIN SysComments as M <br />ON ( M.id = A.cdefault and ObjectProperty(A.cdefault, 'IsConstraint') = 1 ) <br />ORDER BY A.Colid ASC <br /><br /><br />11.2..提取数据库内所有表的字段详细说明的SQL语句 <br /><br />SELECT <br />(case when a.colorder=1 then d.name else ' end) N'表名', <br />a.colorder N'字段序号', <br />a.name N'字段名', <br />(case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then '√'else ' <br />end) N'标识', <br />(case when (SELECT count(*) <br />FROM sysobjects <br />WHERE (name in <br />(SELECT name <br />FROM sysindexes <br />WHERE (id = a.id) AND (indid in <br />(SELECT indid <br />FROM sysindexkeys <br />WHERE (id = a.id) AND (colid in <br />(SELECT colid <br />FROM syscolumns <br />WHERE (id = a.id) AND (name = a.name))))))) AND <br />(xtype = 'PK'))&gt;0 then '√' else ' end) N'主键', <br />b.name N'类型', <br />a.length N'占用字节数', <br />COLUMNPROPERTY(a.id,a.name,'PRECISION') as N'长度', <br />isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0) as N'小数位数', <br />(case when a.isnullable=1 then '√'else ' end) N'允许空', <br />isnull(e.text,') N'默认值', <br />isnull(g.[value],') AS N'字段说明' <br />FROM syscolumns a <br />left join systypes b <br />on a.xtype=b.xusertype <br />inner join sysobjects d <br />on a.id=d.id and d.xtype='U' and d.name&lt;&gt;'dtproperties' <br />left join syscomments e <br />on a.cdefault=e.id <br />left join sysproperties g <br />on a.id=g.id AND a.colid = g.smallid <br />order by object_name(a.id),a.colorder <br /><br />11.3.快速获取表test的记录总数[对大容量表非常有效] <br /><br />快速获取表test的记录总数: <br />select rows from sysindexes where id = object_id(‘test’) and indid in (0,1)<br /><br />update 2 set KHXH=(ID+1)\2 2行递增编号<br />update [23] set id1 = 'No.'+right('00000000'+id,6) where id not like 'No%' //递增<br />update [23] set id1= 'No.'+right('00000000'+replace(id1,'No.','),6) //补位递增<br />delete from [1] where (id%2)=1 <br />奇数<br /><br />替换表名字段<br />update [1] set domurl = replace(domurl,'Upload/Imgswf/','Upload/Photo/') where domurl like '%Upload/Imgswf/%'<br /><br />截位<br />SELECT LEFT(表名, 5)</font></div>
		</div>
<img src ="http://www.blogjava.net/xuechen0721/aggbug/84474.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xuechen0721/" target="_blank">兵临城下</a> 2006-11-30 09:10 <a href="http://www.blogjava.net/xuechen0721/articles/84474.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>