【网学网提醒】:网学会员为您提供SQL语句技巧汇总参考,解决您在SQL语句技巧汇总学习中工作中的难题,参考学习。
一些有用Transat-SQL技巧[持续更新中]
[1]取得当前日期,不包括时间
convert(varchar(10),getdate(),120)格式如:yyyy-mm-dd
convert(varchar(10),getdate(),111)格式如:yyyy/mm/dd
详细格式请参考
CONVERT(data_type[(length)],expression[,style])
[2]collation排序规则
有时连接两个数据库时因为数据库的排序规则[collation]不一样会出现连接两个表时出现如下错误:
Msg446,Level16,State9,Line1
Cannotresolvecollationconflictforequaltooperation.
可以用如下的语法解决:
select*fromdbo.tb_brm_regionwhereregion_idin(selectdistincttms_district_idcollateLatin1_General_BINfromisf_headerwheretms_district_idisnotnull)
其中Latin1_General_BIN可以根据你的需求换成不同的排序规则collation
[3]取得前一个月的第一天和前一个月的最后一天
declare@gdatedatetime
set@gdate=dateadd(Month,-1,dateadd(day,-(day(getdate())-1),getdate()))
declare@edatedatetime
set@edate=convert(varchar(10),dateadd(day,-day(getdate()),getdate()),120)
[4]取得一个星期内的数据
select*fromtablewheredatetime
anddatetime>=convert(varchar(10),dateadd(d,1,getdate()-DATEPART(dw,getdate())),120)
[5]存储过程调用存储过程的数据集
假设我数据库里有个存储过程getMaxId该存储过程没有用output参数,而且已经在很多地方调用,那么我现在要在另外一个存储过程中调用该存储过程,可以使用如下方法:
createprocdoSomeThing
as
createtable#tbTempMaxId
(
maxIdint
)
insertinto#tbTempMaxIdexecgetmaxid
select*from#tbTempMaxId
具体思路:
1.新增一张与存储过程结构一致的临时表
2.用INSERT命令将存储过程结果放入临时表中
[6]如何查看SQLSERVER补丁的版本
select@@version
可以得到如下结果
MicrosoftSQLServer2000-8.00.760(IntelX86)Dec17200214:22:05Copyright(c)1988-2003MicrosoftCorporationStandardEditiononWindowsNT5.0(Build2195:ServicePack4)
[7]如何检查存在临时表
在某些情况下可能会检查是否存在临时表,可以使用下面的代码
IFOBJECT_ID(N'tempdb..#temp1')ISNOTNULL
droptable#temp1
[8]如何检测临时表存在二
ifexists(select*fromdbo.sysobjectswhereid=object_id(N'[dbo].[#TMPcontent]')andOBJECTPROPERTY(id,N'IsUserTable')=1)
droptable[dbo].[#TMPcontent]
[9]如何查询一个表的字段以及字段的格式
SELECT
表名=casewhena.colorder=1thend.nameelse''end,
表说明=casewhena.colorder=1thenisnull(f.value,'')else''end,
字段序号=a.colorder,
字段名=a.name,
标识=cas
ewhenCOLUMNPROPERTY(a.id,a.name,'IsIdentity')=1then'√'else''end,
主键=casewhenexists(SELECT1FROMsysobjectswherextype='PK'andnamein(
SELECTnameFROMsysindexesWHEREindidin(
SELECTindidFROMsysindexkeysWHEREid=a.idANDcolid=a.colid
)))then'√'else''end,
类型=b.name,
占用字节数=a.length,
长度=COLUMNPROPERTY(a.id,a.name,'PRECISION'),
小数位数=isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0),
允许空=casewhena.isnullable=1then'√'else''end,
默认值=isnull(e.text,''),
字段说明=isnull(g.[value],'')
FROMsyscolumnsa
leftjoinsystypesbona.xusertype=b.xusertype
innerjoinsysobjectsdona.id=d.idandd.xtype='U'andd.name<>'dtproperties'
leftjoinsyscommentseona.cdefault=e.id
leftjoinsyspropertiesgona.id=g.idanda.colid=g.smallid
leftjoinsyspropertiesfond.id=f.idandf.smallid=0
--whered.name='department'--如果只查询指定表,加上此条件
orderbya.id,a.colorder
[10]判断两个表的数据是否一致
SELECTCASE
WHEN(SELECTCHECKSUM_AGG(BINARY_CHECKSUM(*))FROM表a)
=(SELECTCHECKSUM_AGG(BINARY_CHECKSUM(*))FROM表b)
THENN'一致'
ELSEN'不一致'END
[11]如何查看SQLSERVER补丁的版本
select@@version
可以得到如下结果
MicrosoftSQLServer2000-8.00.760(IntelX86)Dec17200214:22:05Copyright(c)1988-2003MicrosoftCorporationStandardEditiononWindowsNT5.0(Build2195:ServicePack4)
[12]有时候数据库转移服务器常常会因为表所有者的问题导致数据库不能访问。这时候需要更改表的所有者。一般是将表的所有者改为dbo.
1.将某个表的所有者改为dbo.
sp_changeobjectowner'表名','dbo'
2.将当前库中所有表的所有者全部更改为dbo.
execsp_MSForEachTable'sp_changeobjectowner''?'',''dbo'''
因为库中可能有某些表的所有者本来就是dbo,所以执行会有错误消息,不用理会它,执行完毕就OK了
--如果是要用户表/存储过程/视图/触发器/自定义函数一齐改,则用游标(不要理会错误提示)
declaretbcursorlocalfor
select'sp_changeobjectowner''['+replace(user_name(uid),']',']]')+'].['
+replace(name,']',']]')+']'',''dbo'''
fromsysobjects
wherextypein('U','V','P','TR','FN','IF','TF')andstatus>=0
opentb
declare@snvarchar(4000)
fetchtbinto@s
while@@fetch_status=0
begin
exec(@s)
fetchtbinto@s
end
closetb
deallocatetb
go
来源:yes1000/132.htm
cnblogs/xiaotao823/archive/2007/07/09/811216.html
==============
这篇文章共分三个部分,收
集了在互联网上用来处理MSSQL日期时间的几种方法。这里按我收集的先后排列。
第一部分:SQL的本月统计和本周统计
本月统计(MySQL)
select*frombookingwheremonth(booking_time)=month(curdate())andyear(booking_time)=year(curdate())
本周统计(MySQL)
select*fromspf_bookingwheremonth(booking_time)=month(curdate())andweek(booking_time)=week(curdate())
[SQLServer]
表名为:tableName
时间字段名为:theDate
查询本月的记录
select*fromtableNamewhereDATEPART(mm,theDate)=DATEPART(mm,GETDATE())andDATEPART(yy,theDate)=DATEPART(yy,GETDATE())
查询本周的记录
select*fromtableNamewhereDATEPART(wk,theDate)=DATEPART(wk,GETDATE())andDATEPART(yy,theDate)=DATEPART(yy,GETDATE())
查询本季的记录
select*fromtableNamewhereDATEPART(qq,theDate)=DATEPART(qq,GETDATE())andDATEPART(yy,theDate)=DATEPART(yy,GETDATE())
selectdatediff(day,
dateadd(mm,datediff(mm,'',getdate()),''),
dateadd(mm,datediff(mm,'',getdate()),'1900-02-01'))
选择本月信息
SELECT*
FROM[表名]
WHERE(DATEPART(mm,日期)=@month)AND(DATEPART(yy,日期)=@year)
参考资料:
1、twtpl368.bokee/viewdiary.11124860.html
2、hi.baidu/zjcxy/blog/item/5d4de5fc25721efefd037f44.html
第二部分:SQL日期格式化应用大全
SqlServer中一个非常强大的日期格式化函数
SelectCONVERT(varchar(100),GETDATE(),0):0516200610:57AM
SelectCONVERT(varchar(100),GETDATE(),1):05/16/06
SelectCONVERT(varchar(100),GETDATE(),2):06.05.16
SelectCONVERT(varchar(100),GETDATE(),3):16/05/06
SelectCONVERT(varchar(100),GETDATE(),4):16.05.06
SelectCONVERT(varchar(100),GETDATE(),5):16-05-06
SelectCONVERT(varchar(100),GETDATE(),6):160506
SelectCONVERT(varchar(100),GETDATE(),7):0516,06
SelectCONVERT(varchar(100),GETDATE(),8):10:57:46
SelectCONVERT(varchar(100),GETDATE(),9):0516200610:57:46:827AM
SelectCONVERT(varchar(100),GETDATE(),10):05-16-06
SelectCONVERT(varchar(100),GETDATE(),11):06/05/16
SelectCONVERT(varchar(100),GETDATE(),12):060516
SelectCONVERT(varchar(100),GETDATE(),13):1605200610:57:46:937
SelectCONVERT(varchar(100),GETDATE(),14):10:57:46:967
SelectCONVERT(varchar(100),GETDATE(),20):2006-05-1610:57:47
SelectCONVERT(varchar(100),GETDATE(),21):2006-05-1610:57:47.157
SelectCONVERT(varchar(100),GETDATE(),22):05/16/0610:57:47AM
SelectCONVERT(varchar(100),GETDATE(),23):2006-05-16
SelectCONVERT(varchar(100),GETDATE(),24):10:57:47
SelectCONVERT(varchar(100),GETDATE(),25):2006-05-1610:57:47.250
SelectCONVERT(varchar(100),GETDATE(),100):0516200610:57AM
SelectCONVERT(varchar(100),GETDATE(),101):05/16/2006
SelectCONVERT(varchar(100),GETDATE(),102):2006.05.16
SelectCONVERT(varchar(100),GETDATE(),103):16/05/2006
SelectCONVERT(varchar(100),GETDATE(
),104):16.05.2006
SelectCONVERT(varchar(100),GETDATE(),105):16-05-2006
SelectCONVERT(varchar(100),GETDATE(),106):16052006
SelectCONVERT(varchar(100),GETDATE(),107):0516,2006
SelectCONVERT(varchar(100),GETDATE(),108):10:57:49
SelectCONVERT(varchar(100),GETDATE(),109):0516200610:57:49:437AM
SelectCONVERT(varchar(100),GETDATE(),110):05-16-2006
SelectCONVERT(varchar(100),GETDATE(),111):2006/05/16
SelectCONVERT(varchar(100),GETDATE(),112):20060516
SelectCONVERT(varchar(100),GETDATE(),113):1605200610:57:49:513
SelectCONVERT(varchar(100),GETDATE(),114):10:57:49:547
SelectCONVERT(varchar(100),GETDATE(),120):2006-05-1610:57:49
SelectCONVERT(varchar(100),GETDATE(),121):2006-05-1610:57:49.700
SelectCONVERT(varchar(100),GETDATE(),126):2006-05-16T10:57:49.827
SelectCONVERT(varchar(100),GETDATE(),130):18??????????142710:57:49:907AM
SelectCONVERT(varchar(100),GETDATE(),131):18/04/142710:57:49:920AM
常用:
SelectCONVERT(varchar(100),GETDATE(),8):10:57:46
SelectCONVERT(varchar(100),GETDATE(),24):10:57:47
SelectCONVERT(varchar(100),GETDATE(),108):10:57:49
SelectCONVERT(varchar(100),GETDATE(),12):060516
SelectCONVERT(varchar(100),GETDATE(),23):2006-05-16
参考资料:
webwoo.net/bc/bencandy-26-14479-1.htm
第三部分:SQLServer各种日期计算方法
SQLServer各种日期计算方法
出处:CSDN.NET[2005-02-2210:12:52]作者:xpilot责任编辑:lujiezhen
通常,你需要获得当前日期和计算一些其他的日期,例如,你的程序可能需要判断一个月的第一天或者最后一天。你们大部分人大概都知道怎样把日期进行分割(年、月、日等),然后仅仅用分割出来的年、月、日等放在几个函数中计算出自己所需要的日期!在这篇文章里,我将告诉你如何使用DATEADD和DATEDIFF函数来计算出在你的程序中可能你要用到的一些不同日期。
被过滤广告
在使用本文中的例子之前,你必须注意以下的问题。大部分可能不是所有例子在不同的机器上执行的结果可能不一样,这完全由哪一天是一个星期的第一天这个设置决定。第一天(DATEFIRST)设定决定了你的系统使用哪一天作为一周的第一天。所有以下的例子都是以星期天作为一周的第一天来建立,也就是第一天设置为7。假如你的第一天设置不一样,你可能需要调整这些例子,使它和不同的第一天设置相符合。你可以通过@@DATEFIRST函数来检查第一天设置。
为了理解这些例子,我们先复习一下DATEDIFF和DATEADD函数。DATEDIFF函数计算两个日期之间的小时、天、周、月、年等时间间隔总数。DATEADD函数计算一个日期通过给时间间隔加减来获得一个新的日期。要了解更多的DATEDIFF和DATEADD函数以及时间间隔可以阅
读微软联机帮助。
使用DATEDIFF和DATEADD函数来计算日期,和本来从当前日期转换到你需要的日期的考虑方法有点不同。你必须从时间间隔这个方面来考虑。比如,从当前日期到你要得到的日期之间有多少时间间隔,或者,从今天到某一天(比如1900-1-1)之间有多少时间间隔,等等。理解怎样着眼于时间间隔有助于你轻松的理解我的不同的日期计算例子。
一个月的第一天
第一个例子,我将告诉你如何从当前日期去这个月的最后一天。请注意:这个例子以及这篇文章中的其他例子都将只使用DATEDIFF和DATEADD函数来计算我们想要的日期。每一个例子都将通过计算但前的时间间隔,然后进行加减来得到想要计算的日期。
这是计算一个月第一天的SQL脚本:
SELECTDATEADD(mm,DATEDIFF(mm,0,getdate()),0)
我们把这个语句分开来看看它是如何工作的。最核心的函数是getdate(),大部分人都知道这个是返回当前的日期和时间的函数。下一个执行的函数DATEDIFF(mm,0,getdate())是计算当前日期和“1900-01-0100:00:00.000”这个日期之间的月数。记住:时期和时间变量和毫秒一样是从“1900-01-0100:00:00.000”开始计算的。这就是为什么你可以在DATEDIFF函数中指定第一个时间表达式为“0”。下一个函数是DATEADD,增加当前日期到“1900-01-01”的月数。通过增加预定义的日期“1900-01-01”和当前日期的月数,我们可以获得这个月的第一天。另外,计算出来的日期的时间部分将会是“00:00:00.000”。
这个计算的技巧是先计算当前日期到“1900-01-01”的时间间隔数,然后把它加到“1900-01-01”上来获得特殊的日期,这个技巧可以用来计算很多不同的日期。下一个例子也是用这个技巧从当前日期来产生不同的日期。
本周的星期一
这里我是用周(wk)的时间间隔来计算哪一天是本周的星期一。
SELECTDATEADD(wk,DATEDIFF(wk,0,getdate()),0)
一年的第一天
现在用年(yy)的时间间隔来显示这一年的第一天。
SELECTDATEADD(yy,DATEDIFF(yy,0,getdate()),0)
季度的第一天
假如你要计算这个季度的第一天,这个例子告诉你该如何做。
SELECTDATEADD(qq,DATEDIFF(qq,0,getdate()),0)
当天的半夜
曾经需要通过getdate()函数为了返回时间值截掉时间部分,就会考虑到当前日期是不是在半夜。假如这样,这个例子使用DATEDIFF和DATEADD函数来获得半夜的时间点。
SELECTDATEADD(dd,DATEDIFF(dd,0,getdate()),0)
深入DATEDIFF和DATEADD函数计算
你可以明白,通过使用简单的DATEDIFF和DATEADD函数计算,你可以发现很多不同的可能有意义的日期。
目前为止的所有例子只是仅仅计算当前的时间和“1900-01-01”之间的时间间隔数量,然后把它加到“1900-01-01”的时间间隔上来计算出日期。假定你修改时间间隔的数量,或者使用不同的时间间隔来调用DATEADD函数,或者减去时间间隔而不是增加,那么通过这些小的调整你可以发现和多不同的日期。
这里有四个例子使用另外一个DATEADD函数来计算最后一天来分别替换DATEADD函数前后两个时间间隔。
上个月的最后一天
这是一个计算上个月最后一天的例子。它通过从一个月的最后一天这个例子上减去3毫秒来获得。有一点要记住,在SqlServer中时间是精确到3毫秒。这就是为什么我需要减去3毫秒来获得我要的日期和时间。
SELECTdateadd(ms,-3,DATEADD(mm,DATEDIFF(mm,0,getdate()),0))
计算出来的日期的时间部分包含了一个SqlServer可以记录的一天的最后时刻(“23:59:59:997”)的时间。
去年的最后一天
连接上面的例子,为了要得到去年的最后一天,你需要在今年的第一天上减去3毫秒。
SELECTdateadd(ms,-3,DATEADD(yy,DATEDIFF(yy,0,getdate()),0))
本月的最后一天
现在,为了获得本月的最后一天,我需要稍微修改一下获得上个月的最后一天的语句。修改需要给用DATEDIFF比较当前日期和“1900-01-01”返回的时间间隔上加1。通过加1个月,我计算出下个月的第一天,然后减去3毫秒,这样就计算出了这个月的最后一天。这是计算本月最后一天的SQL脚本。
SELECTdateadd(ms,-3,DATEADD(mm,DATEDIFF(m,0,getdate())+1,0))
本年的最后一天
你现在应该掌握这个的做法,这是计算本年最后一天脚本
SELECTdateadd(ms,-3,DATEADD(yy,DATEDIFF(yy,0,getdate())+1,0))。
本月的第一个星期一
好了,现在是最后一个例子。这里我要计算这个月的第一个星期一。这是计算的脚本。
selectDATEADD(wk,DATEDIFF(wk,0,
dateadd(dd,6-datepart(day,getdate()),getdate())
),0)
在这个例子里,我使用了“本周的星期一”的脚本,并作了一点点修改。修改的部分是把原来脚本中“getdate()”部分替换成计算本月的第6天,在计算中用本月的第6天来替换当前日期使得计算可以获得这个月的第一个星期一。
总结
我希望这些例子可以在你用DATEADD和DATEDIFF函数计算日期时给你一点启发。通过使用这个计算日期的时间间隔的数学
方法,我发现为了显示两个日期之间间隔的有用历法是有价值的。注意,这只是计算出这些日期的一种方法。要牢记,还有很多方法可以得到相同的计算结果。假如你有其他的方法,那很不错,要是你没有,我希望这些例子可以给你一些启发,当你要用DATEADD和DATEDIFF函数计算你程序可能要用到的日期时。
---------------------------------------------------------------
附录,其他日期处理方法
1)去掉时分秒
declare@datetime
set@=getdate()--'2003-7-110:00:00'
SELECT@,DATEADD(day,DATEDIFF(day,0,@),0)
2)显示星期几
selectdatename(weekday,getdate())
3)如何取得某个月的天数
declare@mint
set@m=2--月份
selectdatediff(day,'2003-'+cast(@masvarchar)+'-15','2003-'+cast(@m+1asvarchar)+'-15')
另外,取得本月天数
selectdatediff(day,cast(month(GetDate())asvarchar)+'-'+cast(month(GetDate())asvarchar)+'-15',cast(month(GetDate())asvarchar)+'-'+cast(month(GetDate())+1asvarchar)+'-15')
或者使用计算本月的最后一天的脚本,然后用DAY函数区最后一天
SELECTDay(dateadd(ms,-3,DATEADD(mm,DATEDIFF(m,0,getdate())+1,0)))
4)判断是否闰年:
SELECTcaseday(dateadd(mm,2,dateadd(ms,-3,DATEADD(yy,DATEDIFF(yy,0,getdate()),0))))when28then'平年'else'闰年'end
或者
selectcasedatediff(day,datename(year,getdate())+'-02-01',dateadd(mm,1,datename(year,getdate())+'-02-01'))
when28then'平年'else'闰年'end
5)一个季度多少天
declare@mtinyint,@timesmalldatetime
select@m=month(getdate())
select@m=casewhen@mbetween1and3then1
when@mbetween4and6then4
when@mbetween7and9then7
else10end
select@time=datename(year,getdate())+'-'+convert(varchar(10),@m)+'-01'
selectdatediff(day,@time,dateadd(mm,3,@time))
作者Blog:blog.csdn.net/xpilot/
附:我在实际应用中的例子:
获取本月的点击,使用第一部分提供的方法,即detepart
select*fromnews_hitswhereDATEPART(mm,ReadTime)=DATEPART(mm,GETDATE())andDATEPART(yy,ReadTime)=DATEPART(yy,GETDATE())
获取本月的点击,使用来自于asp(vbscript)的思维,即datediff
select*fromnews_hitswhereDATEDIFF(MM,ReadTime,GETDATE())=0--DATEPART(mm,ReadTime)=DATEPART(mm,GETDATE())andDATEPART(yy,ReadTime)=DATEPART(yy,GETDATE())
获取本周的点击
select*fromnews_hitswhereDATEDIFF(WW,ReadTime,GETDATE())=0
获取本周的第一天(来自于第三部分的方法)
SELECTDATEADD(wk,DATEDIFF(wk,0,getdate()),0)
用EXISTS避免重复插入已经存在的数据
insertintodomain_branch
(domain_id,branch_id,update_user
_id,update_date,obsoleted)
select'M000042001',branch_id,'S700010000',getdate(),'F'fromdomain_branchb1wheredomain_id='M000032001'
andnotEXISTS
(select*fromdomain_branchb2whereb1.branch_id=b2.branch_idandb2.domain_id='M000042001')
用递归的方式获取树型关系表中的某个分支的所有子节点
createfunctiondbo.f_temp_rollout_fixMultMgr
(
@groupIdvarchar(12)
)
returns@tGroupIdtable(groupIdvarchar(12),levint)
begin
declare@Countasint
set@count=1
insert@tgroupIdselect@groupid,@count
while@@rowcount<>0
begin
set@count=@count+1
insert@tgroupid
selectgroup_id,@countfromoc_test_group_temp_rolloutg,@tgroupidtg
whereg.under_group_id=tg.groupidandlev=@count-1
end
return
end