SQL:在范围外或范围内查找日期匹配

时间:2017-02-21 15:00:37

标签: sql sql-server tsql

在Microsoft SQL Server中,我们有此表记录用户的属性更改:

ID | userID | prop | changeDate
-------------------------------
 4   23      B       2017-02-18
 1   14      D       2013-05-19
 2   15      C       2014-04-10
 3   23      A       2016-01-11

我想要查询此表并在一系列日期中查找活动属性。

例如2016-08-012017-01-01期间我希望获得userID 23道具A,因为这是该用户的活动属性,直到它被更改为止2017-02-18

我从changeDate BETWEEN '2016-08-01' and '2017-01-01'开始,但仅涵盖了我确切开始日期的情况。

我变得有点疯狂。这个数据是否可以实现此任务?或者我可能会问错误的问题?

2 个答案:

答案 0 :(得分:2)

对于这种类型的表,典型的问题是“特定日期的给定用户属性是什么?”

这回答了这个问题:

select pc.*
from (select pc.*,
             row_number() over (partition by userId order by changeDate desc) as seqnum
      from propertychanges pc
      where changeDate <= @AsOfDate
     ) pc
where seqnum = 1;

答案 1 :(得分:1)

自我加入可以在这里提供帮助。

CREATE TABLE x (ID INT, userID INT, prop CHAR(1), changeDate DATETIME)

INSERT INTO x
  VALUES ( 4, 23, 'B', '20170218' ),
         ( 1, 14, 'D', '20130519' ),
         ( 2, 15, 'C', '20140410' ),
         ( 3, 23, 'A', '20160111' )

; WITH cte AS (
  SELECT  x1.userID, x1.prop, x1.changeDate AS StartDate, MIN(x2.changeDate) AS ExitDate
  FROM    x x1
          LEFT OUTER JOIN x  x2
                  ON x1.changeDate < x2.changeDate
  GROUP BY x1.userID, x1.prop, x1.changeDate
)

SELECT  *
FROM    cte
WHERE   Startdate > = '20160801' 
  AND   ( ExitDate IS NULL OR ExitDate < '20170101' )

这可以为您提供所需的内容

userID | prop | StartDate               | ExitDate
--------------------------------------------------
 23       B      2017-02-18 00:00:00.000   NULL