有一个类似顶、赞功能的记录表,
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语句,主要是这个日期范围该怎么计算?

解决方案 »

  1.   

    --最近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)
      

  2.   

    /*
    有一个类似顶、赞功能的记录表,
    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 
      

  3.   

               
     
    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