最近我每周都要去统计“华语好声音”和“三个一”活动的一周文章列表。所以在条件语句中,总是少不了限制时间。例如,上周统计“华语好声音”的一个条件子句就是
DATEADD(hour,7, created)>='2018-01-27 00:00:00'
因为系统时间同北京时间相差7小时,所以要用DATEADD()函数把数据库里的created字段时间后移动7小时。
可是,我不想每周统计的时候,都要去看一下日历,看一下最近的周六的日期,因为这样太费时间了,也不是一个真正的程序员应该干的事呀。
于是,我需要根据当前的时间来获取上一个周六的具体时间。
首先,要想办法知道现在是周几。上网,搜了一下,Datepart()这个函数有这个功能。我分别运行了
SELECT Datepart(weekday, getdate())
SELECT Datepart(wk, getdate())
SELECT Datepart(ww, getdate())
SELECT Datepart(weekday, getdate())
SELECT Datepart(dw, getdate())
运行的结果分别是5 6 6 5 5,可是,今天周四。。。。。
肿么回事?肿么办?
于是我各种百度谷歌
最后发现了这么一句
SELECT Datepart(weekday, getdate() +@@DateFirst - 1)
运行了一下,果然显示的是4。但我不会就此罢休的,打破砂锅是必须的!
于是我select @@@DateFirst,显示是7。
然后我试了一下
set DateFirst 6
SELECT Datepart(weekday, getdate())
SELECT Datepart(wk, getdate())
SELECT Datepart(ww, getdate())
SELECT Datepart(weekday, getdate())
SELECT Datepart(dw, getdate())
结果变成了 6 6 6 6 6。
再试:
set DateFirst 5
SELECT Datepart(weekday, getdate())
SELECT Datepart(wk, getdate())
SELECT Datepart(ww, getdate())
SELECT Datepart(weekday, getdate())
SELECT Datepart(dw, getdate())
结果变成了 7 6 6 7 7。
set DateFirst 4
SELECT Datepart(weekday, getdate())
SELECT Datepart(wk, getdate())
SELECT Datepart(ww, getdate())
SELECT Datepart(weekday, getdate())
SELECT Datepart(dw, getdate())
结果是 1 7 7 1 1
set DateFirst 3
SELECT Datepart(weekday, getdate())
SELECT Datepart(wk, getdate())
SELECT Datepart(ww, getdate())
SELECT Datepart(weekday, getdate())
SELECT Datepart(dw, getdate())
结果是 2 7 7 2 2
试到这里里就不用再试了, 第一、四、五个查询结果是根据@@@DateFirst的值来移动的。当我set DateFirst 4时,第一、四、五个查询结果是1,根据DateFirst字面再理解一下,可以理解了,原来DateFirst是设置每周的第1天是周几。
于是我臭不要脸的试了一下 set DateFirst 0和set DateFirst 8,然后系统果断的回复了我:
Error 2742: SET DATEFIRST 0 is out of range.
Error 2742: SET DATEFIRST 8 is out of range.
验证我的猜测是正确的哈哈哈哈。
继续谷歌百度,原来@@@DateFirst这个是设定以周几做为一周的第1天的参数。默认的是周日为第一天。select @@@DateFirst,显示果然是7。
wk 和ww这两个参数又是什么鬼呢?于是,我首先设好set DateFirst 1,然后我把这周的日期全试了一下:
SELECT Datepart(wk, '2018-02-05')
SELECT Datepart(ww, '2018-02-05')
SELECT Datepart(wk, '2018-02-06')
SELECT Datepart(ww, '2018-02-06')
SELECT Datepart(wk, '2018-02-07')
SELECT Datepart(ww, '2018-02-07')
SELECT Datepart(wk, '2018-02-08')
SELECT Datepart(ww, '2018-02-08')
SELECT Datepart(wk, '2018-02-09')
SELECT Datepart(ww, '2018-02-09')
SELECT Datepart(wk, '2018-02-10')
SELECT Datepart(ww, '2018-02-10')
SELECT Datepart(wk, '2018-02-11')
SELECT Datepart(ww, '2018-02-11')
结果全是6,继续试:
SELECT Datepart(wk, '2018-02-12')
SELECT Datepart(ww, '2018-02-12')
结果变成了7,我好像有点感觉了。我于是我找了两个特残的日又试了一下
SELECT Datepart(wk, '2018-01-01')
SELECT Datepart(ww, '2018-01-01')
SELECT Datepart(wk, '2017-12-31')
SELECT Datepart(ww, '2017-12-31')
结果显示为1 1 53 53,恍然大悟呀,原来是查询一年的第几周。
一路上遇见的都搞清楚了,继续查询上一个周六的日期。接下来就简单了,把当前的日期减掉从周六度过的日子就行了:
set DateFirst 6 /* 索性把周六设为第1天 */
select DATEADD(day, 1-Datepart(weekday, DATEADD(hour,7,getdate() ) ) ,DATEADD(hour,7,getdate() ))
然而我的活动都是在周六以后统计,统计的范围是再上一个周六到,到上一个周五。并且开始的时间是00:00:00 结束的时间23:59:59.如何能从时间中获取日期,再加上指定时间呢, 问题又来了。
Datename()函数要分别取年、月、日再用。
我还想到用转换函数convert(),一种是转字符串再接上指定的时间,可以直接用来和时间字段比较。
或者将时间转化成日期,再转成时间,应该会变成00:00:00不过如果移动的话还要再转成datetime型。
最后我选择第二种,先声明一个变量 declare @bjt datetime = DATEADD(hour,7,getdate() ),用来存储北京时间,这样减少重复调用函数,同时也不会由于getdate()变化带来结果差异。
因为steemsql时间比北京时间晚7小时,所以要把时间移动到周五:
移动到周五的时间
DATEADD(day, -Datepart(weekday, @bjt) ,@bjt)
取日期
convert(varchar(10),DATEADD(day, -Datepart(weekday, @bjt) ,@bjt) ,120)
取北京时间0点,即steemsql时间17点的字符串
convert(varchar(10),DATEADD(day, -Datepart(weekday, @bjt) ,@bjt) ,120)+' 17:00:00'
将0点的时间的字符串转成datetime型
convert(datetime, convert(varchar(10),DATEADD(day, -Datepart(weekday, @bjt) ,@bjt) ,120)+' 17:00:00')
所以上个周六的0点和上上个周六的0点对应的steemsql时间分别是:
declare @end datetime =convert(datetime, convert(varchar(10),DATEADD(day, --Datepart(weekday, @bjt) ,@bjt) ,120)+' 17:00:00')
declare @start datetime =convert(datetime, convert(varchar(10),DATEADD(day, -7-Datepart(weekday, @bjt) ,@bjt) ,120)+' 17:00:00')
所以这个子句应该是:
created >=@start and created<@end
纯sql感觉有些复杂。等我学会python(或者C#)就好了吧。好吧我承认我啥也不会。
欢迎各位偶像莅临指导,不胜荣幸&感激!感谢批评和帮助!!
功夫不负有心人,就这样被你试出来了。
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
哈哈还是你懂我哈哈
其实我还试了很多相关、但是实现这个功能没有用的东西。
但只有这样才能边干边学习呀!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
向你学习,边干边学,最有效率。
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
@tvb 一姐果然不是盖的,我看了以上的steemsql,真是"雾里看花" 有看没懂的感觉 (甚至开始有些晕头转向@_@)
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
你想懂就能懂啦
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
@tvb, 干的漂亮!
情人节貌似快到了,@cn-cutie.pie 可可 我们去哪里浪漫一下?
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
好瘋狂啊...... 怎麽這裏好像每一個人都懂寫code 但我偏偏以前沒有學好........
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
我也不怎么会呀
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
steemsql比steemjs好用多了,(´;︵;`)
steemjs坑好多,不好用。
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
我还想研究研究steem.js呢。再说坑多你正好提bug
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
@tvb, 我好欣赏你滴~~~
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
你男朋友呢
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
辛苦你了,一姐!
早点休息,身体重要!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
你也是呀,赶紧睡呀,大半夜就咱俩不睡哈哈这可不好哈哈
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
哇塞,好高深好崇拜@tvb!编程能力这么强。我都看痴了
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
谢谢
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
你真是什么都懂一点啊……研究的东西越来越深奥了……
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
其实很简单的,内行人一看就会笑话我的
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
@tvb姐,不久前发现有这个SQL tutorial :
https://www.w3schools.com/sql/default.asp
datepart的部分:
https://www.w3schools.com/sql/func_sqlserver_datepart.asp
interval
Required. The time/date part to return. Can be one of the following
values:
year, yyyy, yy = Year
quarter, qq, q = Quarter
month, mm, m = month
dayofyear = Day of the year
day, dy, y = Day
week, ww, wk = Week
weekday, dw, w = Weekday
hour, hh = hour
minute, mi, n = Minute
second, ss, s = Second
millisecond, ms = Millisecond
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
有一些SQL Server Date Functions可以用
https://www.w3schools.com/sql/sql_ref_sqlserver.asp
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
我用的就是这个函数,但不是你想的那么简单的直接就能得到星期几的。
何况我不只是想要知道现在星期几,你能不能仔细看看人家文章。。。。
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
我看了,后面那个部分是神来之笔,很厉害! 👍
只是刚好看到有tutorial, 可以方便TVB姐不用测试function的参数是什么。
还有一些其他Date Functions可以玩玩。😊
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
测试的过程也是一种收获,不然我记不住。而且@@@datefirst的问题我总是要试试才能弄明白的。Datepart函数在星期这个问题上不能直接用
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
我真是膜拜你啊,哈哈哈!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
请教一姐,如何访问steemsql?使用什么工具啊?
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
linqpad
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
谢谢,给你点赞。
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit