求SQL语句,日期计算

postcha 2014-08-18 02:32:54
有一个类似顶、赞功能的记录表,
id,contentid,userid,goodorbad,crtime
字段说明:id是自增列。contentid,userid是int类型,外键。goodorbad是int,只存0或1,1代表好,0代表不好。crtime是指添加日期,是datetime类型(2014-08-18 14:17:354)

请分别输出最近8小时、今天、24小时以内、本周、最近30天、本月,支持或反对最多的记录,倒序排列。

求以上SQL语句,主要是这个日期范围该怎么计算?
...全文
300 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
nikolaichow 2014-08-20
  • 打赏
  • 举报
回复
DATEADD (Transact-SQL) 发送反馈 请参阅 全部折叠全部展开 语言筛选器: 全部语言筛选器: 多个语言筛选器: Visual Basic语言筛选器: C#语言筛选器: C++语言筛选器: J#语言筛选器: JScript Visual Basic(声明) C# C++ J# JScript 将指定 number 时间间隔(有符号整数)与指定 date 的指定 datepart 相加后,返回该 date。 有关所有 Transact-SQL 日期和时间数据类型及函数的概述,请参阅日期和时间数据类型及函数 (Transact-SQL)。有关日期和时间数据类型及函数共有的信息和示例,请参阅使用日期和时间数据。 主题链接图标 Transact-SQL 语法约定 语法 DATEADD (datepart , number , date ) 参数 datepart 是与 integer number 相加的 date 部分。下表列出了所有有效的 datepart 参数。用户定义的变量等效项是无效的。 datepart 缩写 year yy, yyyy quarter qq, q month mm, m dayofyear dy, y day dd, d week wk, ww weekday dw, w hour hh minute mi, n second ss, s millisecond ms microsecond mcs nanosecond ns number 是一个表达式,可以解析为与 date 的 datepart 相加的 int。用户定义的变量是有效的。 如果您指定一个带小数的值,则将小数截去且不进行舍入。 date 是一个表达式,可以解析为 time、date、smalldatetime、datetime、datetime2 或 datetimeoffset 值。date 可以是表达式、列表达式、用户定义的变量或字符串文字。如果表达式是字符串文字,则它必须解析为一个 datetime 值。为避免不确定性,请使用四位数年份。有关两位数年份的信息,请参阅 two digit year cutoff 选项。 返回类型 返回数据类型为 date 参数的数据类型,字符串文字除外。 字符串文字的返回数据类型为 datetime。如果字符串文字的秒数小数位数超过三位 (.nnn) 或包含时区偏移量部分,将引发错误。 返回值 datepart 参数 dayofyear、day 和 weekday 返回相同的值。 每个 datepart 及其缩写都返回相同的值。 如果 datepart 为 month 且 date 月份比返回月份的天数多,因而 date 中的日在返回月份中不存在,则返回返回月份的最后一天。例如,9 月份有 30 天;因此,下面两个语句返回 2006-09-30 00:00:00.000: SELECT DATEADD(month, 1, '2006-08-30') SELECT DATEADD(month, 1, '2006-08-31') number 参数 number 参数不能超出 int 的范围。在下面的语句中,number 的参数超出 int 范围 1。将返回如下错误消息:“将表达式转换为数据类型 int 时出现算术溢出错误。” 复制代码 SELECT DATEADD(year,2147483648, '2006-07-31'); SELECT DATEADD(year,-2147483649, '2006-07-31'); date 参数 date 参数不能增加至其数据范围之外的值。在下面的语句中,与 date 值相加的 number 值超出了 date 数据类型的范围。将返回如下错误消息:“将值添加到 'datetime' 列导致溢出。” 复制代码 SELECT DATEADD(year,2147483647, '2006-07-31'); SELECT DATEADD(year,-2147483647, '2006-07-31'); date 为 smalldatetime 型、datepart 为秒或秒小数部分时的返回值 smalldatetime 值的秒数部分始终为 00。如果 date 的数据类型为 smalldatetime,则适用以下准则: 如果 datepart 为 second 且 number 介于 -30 和 +29 之间,则不执行加法。 如果 datepart 为 second 且 number 小于 -30 或大于 +29,则以一分钟为起值执行加法。 如果 datepart 为 millisecond 且 number 介于 -30001 和 +29998 之间,则不执行加法。 如果 datepart 为 millisecond 且 number 小于 -30001 或大于 +29998,则以一分钟为起值执行加法。 注释 DATEADD 可用在 SELECT <list>、WHERE、HAVING、GROUP BY 和 ORDER BY 子句中。 秒的小数部分精度 不允许将日期部分 microsecond 或 nanosecond 与数据类型为 smalldatetime、date 和 datetime 的 date 相加。 毫秒的小数位数为 3 (.123)。微秒的小数位数为 6 (.123456)。纳秒的小数位数为 9 (.123456789)。time、datetime2 和 datetimeoffset 数据类型的最大小数位数为 7 (.1234567)。如果 datepart 为 nanosecond,则 number 必须为 100 才能使 date 的秒小数部分增加。介于 1 和 49 之间的 number 向下舍入为 0,介于 50 和 99 之间的 number 向上舍入为 100。 以下语句加的 datepart 为 millisecond、microsecond 或 nanosecond。 复制代码 DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111' SELECT '1 millisecond' ,DATEADD(millisecond,1,@datetime2) UNION ALL SELECT '2 milliseconds', DATEADD(millisecond,2,@datetime2) UNION ALL SELECT '1 microsecond', DATEADD(microsecond,1,@datetime2) UNION ALL SELECT '2 microseconds', DATEADD(microsecond,2,@datetime2) UNION ALL SELECT '49 nanoseconds', DATEADD(nanosecond,49,@datetime2) UNION ALL SELECT '50 nanoseconds', DATEADD(nanosecond,50,@datetime2) UNION ALL SELECT '150 nanoseconds', DATEADD(nanosecond,150,@datetime2); /* Returns: 1 millisecond 2007-01-01 13:10:10.1121111 2 milliseconds 2007-01-01 13:10:10.1131111 1 microsecond 2007-01-01 13:10:10.1111121 2 microseconds 2007-01-01 13:10:10.1111131 49 nanoseconds 2007-01-01 13:10:10.1111111 50 nanoseconds 2007-01-01 13:10:10.1111112 150 nanoseconds 2007-01-01 13:10:10.1111113 */ 时区偏移量 不允许对时区偏移量执行加法。 示例 A. 以 1 为增量递增 datepart 下面的每条语句以 1 为增量递增 datepart。 复制代码 DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111' SELECT 'year', DATEADD(year,1,@datetime2) UNION ALL SELECT 'quarter',DATEADD(quarter,1,@datetime2) UNION ALL SELECT 'month',DATEADD(month,1,@datetime2) UNION ALL SELECT 'dayofyear',DATEADD(dayofyear,1,@datetime2) UNION ALL SELECT 'day',DATEADD(day,1,@datetime2) UNION ALL SELECT 'week',DATEADD(week,1,@datetime2) UNION ALL SELECT 'weekday',DATEADD(weekday,1,@datetime2) UNION ALL SELECT 'hour',DATEADD(hour,1,@datetime2) UNION ALL SELECT 'minute',DATEADD(minute,1,@datetime2) UNION ALL SELECT 'second',DATEADD(second,1,@datetime2) UNION ALL SELECT 'millisecond',DATEADD(millisecond,1,@datetime2) UNION ALL SELECT 'microsecond',DATEADD(microsecond,1,@datetime2) UNION ALL SELECT 'nanosecond',DATEADD(nanosecond,1,@datetime2); /* Year 2008-01-01 13:10:10.1111111 quarter 2007-04-01 13:10:10.1111111 month 2007-02-01 13:10:10.1111111 dayofyear 2007-01-02 13:10:10.1111111 day 2007-01-02 13:10:10.1111111 week 2007-01-08 13:10:10.1111111 weekday 2007-01-02 13:10:10.1111111 hour 2007-01-01 14:10:10.1111111 minute 2007-01-01 13:11:10.1111111 second 2007-01-01 13:10:11.1111111 millisecond 2007-01-01 13:10:10.1121111 microsecond 2007-01-01 13:10:10.1111121 nanosecond 2007-01-01 13:10:10.1111111 */ B. 在一条语句中将 datepart 增加一级以上 下面的每条语句将 datepart 与一个足够大的 number 相加,使得 date 的上一级 datepart 也增大。 复制代码 DECLARE @datetime2 datetime2; SET @datetime2 = '2007-01-01 01:01:01.1111111'; --Statement Result ------------------------------------------------------------------- SELECT DATEADD(quarter,4,@datetime2); --2008-01-01 01:01:01.110 SELECT DATEADD(month,13,@datetime2); --2008-02-01 01:01:01.110 SELECT DATEADD(dayofyear,365,@datetime2); --2008-01-01 01:01:01.110 SELECT DATEADD(day,365,@datetime2); --2008-01-01 01:01:01.110 SELECT DATEADD(week,5,@datetime2); --2007-02-05 01:01:01.110 SELECT DATEADD(weekday,31,@datetime2); --2007-02-01 01:01:01.110 SELECT DATEADD(hour,23,@datetime2); --2007-01-02 00:01:01.110 SELECT DATEADD(minute,59,@datetime2); --2007-01-01 02:00:01.110 SELECT DATEADD(second,59,@datetime2); --2007-01-01 01:02:00.110 SELECT DATEADD(millisecond,1,@datetime2); --2007-01-01 01:01:01.110 C. 使用表达式作为 number 和 date 形参的实参 以下示例使用不同类型的表达式作为 number 和 date 形参的实参。 将列指定为 date 下例将每个 OrderDate 加上 2 天以计算新的 PromisedShipDate。 复制代码 USE AdventureWorks2008R2; GO SELECT SalesOrderID ,OrderDate ,DATEADD(day,2,OrderDate) AS PromisedShipDate FROM Sales.SalesOrderHeader; 将用户定义的变量指定为 number 和 date 下例将用户定义的变量指定为 number 和 date 的参数。 复制代码 DECLARE @days int; DECLARE @datetime datetime; SET @days = 365; SET @datetime = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */ SELECT DATEADD(day, @days, @datetime); 将标量系统函数指定为 date 下例指定 SYSDATETIME 用作 date。 复制代码 SELECT DATEADD(month, 1, SYSDATETIME()); 将标量子查询和标量函数指定为 number 和 date 下例将标量子查询和标量函数 MAX(ModifiedDate) 用作 number 和 date 的参数。(SELECT TOP 1 BusinessEntityID FROM Person.Person) 是 number 形参的假实参,用来说明如何从值列表中选择 number 实参。 复制代码 USE AdventureWorks2008R2; GO SELECT DATEADD(month,(SELECT TOP 1 BusinessEntityID FROM Person.Person), (SELECT MAX(ModifiedDate) FROM Person.Person)); 将常量指定为 number 和 date 下例将数值和字符常量用作 number 和 date 的参数。 SELECT DATEADD(minute, 1, ' 2007-05-07 09:53:01.0376635'); 将数值表达式和标量系统函数指定为 number 和 date 下例将数值表达式 (-(10/2))、一元运算符 (-)、算术运算符 (/) 和标量系统函数 (SYSDATETIME) 用作 number 和 date 的参数。 复制代码 SELECT DATEADD(month,-(10/2), SYSDATETIME()); 将排名函数指定为 number 下例将排名函数用作 number 的参数。 复制代码 USE AdventureWorks2008R2; GO SELECT p.FirstName, p.LastName ,DATEADD(day,ROW_NUMBER() OVER (ORDER BY a.PostalCode),SYSDATETIME()) AS 'Row Number' FROM Sales.SalesPerson AS s INNER JOIN Person.Person AS p ON s.BusinessEntityID = p.BusinessEntityID INNER JOIN Person.Address AS a ON a.AddressID = p.BusinessEntityID WHERE TerritoryID IS NOT NULL AND SalesYTD <> 0; 将聚合开窗函数指定为 number 下例将聚合开窗函数用作 number 的参数。 复制代码 USE AdventureWorks2008R2; GO SELECT SalesOrderID, ProductID, OrderQty ,DATEADD(day,SUM(OrderQty) OVER(PARTITION BY SalesOrderID),SYSDATETIME()) AS 'Total' FROM Sales.SalesOrderDetail WHERE SalesOrderID IN(43659,43664); GO
zhendemo_13 2014-08-18
  • 打赏
  • 举报
回复
/*
有一个类似顶、赞功能的记录表,
id,contentid,userid,goodorbad,crtime
字段说明:id是自增列。contentid,userid是int类型,外键。goodorbad是int,只存0或1,1代表好,0代表不好。crtime是指添加日期,是datetime类型(2014-08-18 14:17:354) 

请分别输出最近8小时、今天、24小时以内、本周、最近30天、本月,支持或反对最多的记录,倒序排列。

 求以上SQL语句,主要是这个日期范围该怎么计算? 
 */
 
 -- 环境
 IF EXISTS(SELECT 1 FROM sys.objects WHERE type='U' AND name='good')
 DROP TABLE dbo.good
 go
 CREATE TABLE dbo.good(id INT IDENTITY(1,1) NOT NULL  PRIMARY KEY,contentid INT NOT NULL,userid INT NOT NULL ,
                       goodorbad bit NOT null,crtime datetime)
 go                     
 INSERT INTO dbo.good(contentid,userid,goodorbad,crtime)                      
 SELECT 8,1,1,'2014-7-31 20:00:00'
 INSERT INTO dbo.good(contentid,userid,goodorbad,crtime)                        
 SELECT 8,1,1,'2014-8-1 13:00:00'
 INSERT INTO dbo.good(contentid,userid,goodorbad,crtime)                        
 SELECT 9,1,0,'2014-8-1 18:09:00'
  INSERT INTO dbo.good(contentid,userid,goodorbad,crtime)                         
 SELECT 10,1,1,'2014-8-8 20:00:00'
 INSERT INTO dbo.good(contentid,userid,goodorbad,crtime)                        
 SELECT 10,1,1,'2014-8-11 16:00:00'
 INSERT INTO dbo.good(contentid,userid,goodorbad,crtime)                      
 SELECT 8,1,1,'2014-8-15 20:00:00'
 INSERT INTO dbo.good(contentid,userid,goodorbad,crtime)                   
 SELECT 10,1,1,'2014-8-18 10:00:00'
  INSERT INTO dbo.good(contentid,userid,goodorbad,crtime)                   
 SELECT 8,1,0,'2014-8-18 11:00:00'
 GO


--@goodorbad = 1代表好,@goodorbad =0代表不好
DECLARE @goodorbad BIT 
SET @goodorbad = 1
--8小时
SELECT  TOP 1 contentid,COUNT(1)count 
 FROM dbo.good
 WHERE crtime BETWEEN DATEADD(HOUR,-8,GETDATE()) AND GETDATE() AND goodorbad = @goodorbad
 GROUP BY contentid,goodorbad
 ORDER BY count  DESC 
 --24小时
SELECT  TOP 1 contentid,COUNT(1)count 
 FROM dbo.good
 WHERE crtime BETWEEN DATEADD(HOUR,-24,GETDATE()) AND GETDATE() AND goodorbad = @goodorbad
 GROUP BY contentid,goodorbad
 ORDER BY count  DESC 
--今天
SELECT  TOP 1 contentid,COUNT(1)count 
 FROM dbo.good
 WHERE DATEPART(DAY,crtime) =DATEPART(DAY,GETDATE())
      AND goodorbad = @goodorbad
 GROUP BY contentid,goodorbad
 ORDER BY count  DESC 
 --本周
SELECT  TOP 1 contentid,COUNT(1)count 
 FROM dbo.good
 WHERE  DATEPART(WEEK,crtime) =DATEPART(WEEK,GETDATE())
      AND goodorbad = @goodorbad
 GROUP BY contentid,goodorbad
 ORDER BY count  DESC 
 --最近30天
 SELECT  TOP 1 contentid,COUNT(1)count 
 FROM dbo.good
 WHERE  crtime BETWEEN DATEADD(DAY,-30,GETDATE()) AND GETDATE() AND goodorbad = @goodorbad
 GROUP BY contentid,goodorbad
 ORDER BY count  DESC 
 --本月
 SELECT  TOP 1 contentid,COUNT(1)count 
 FROM dbo.good
 WHERE  DATEPART(MONTH,crtime) =DATEPART(MONTH,GETDATE())
      AND goodorbad = @goodorbad
 GROUP BY contentid,goodorbad
 ORDER BY count  DESC 
Tiger_Zhao 2014-08-18
  • 打赏
  • 举报
回复
--最近8小时
WHERE crtime >= DateAdd(hour,-8,GetDate())
--今天
WHERE crtime >= Convert(datetime,
Convert(varchar(10),
GetDate(),
120),
120)
--最近24小时以内
WHERE crtime >= DateAdd(hour,-24,GetDate())
--本周
WHERE DatePart(week,crtime) = DatePart(week,GetDate())
--本月
WHERE crtime >= Convert(datetime,
Convert(varchar(7),
GetDate(),
120)+'-01',
120)

34,575

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧